home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / SNNSV32.ZIP / SNNSv3.2 / kernel / sources / kernel.c < prev    next >
C/C++ Source or Header  |  1994-04-25  |  105KB  |  3,717 lines

  1. /*****************************************************************************
  2.   FILE           : kernel.c
  3.   SHORTNAME      : kernel.c
  4.   SNNS VERSION   : 3.2
  5.  
  6.   PURPOSE        : SNNS Kernel
  7.   NOTES          :
  8.  
  9.   AUTHOR         : Niels Mache
  10.   DATE           : 20.02.90
  11.  
  12.   CHANGED BY     : Sven Doering, Michael Vogt, Guenter Mamier
  13.   IDENTIFICATION : @(#)kernel.c    1.35 4/14/94
  14.   SCCS VERSION   : 1.35
  15.   LAST CHANGE    : 4/14/94
  16.  
  17.              Copyright (c) 1990-1994  SNNS Group, IPVR, Univ. Stuttgart, FRG
  18.  
  19. ******************************************************************************/
  20. #define  SNNS_KERNEL
  21.  
  22. #include <stdlib.h>
  23. #include <stdio.h>
  24. #include <ctype.h>
  25. #include <memory.h>
  26. #include <math.h>
  27.  
  28. #include "kr_typ.h"     /*  Kernel Types and Constants  */
  29. #include "kr_const.h"     /*  Constant Declarators for SNNS-Kernel  */
  30. #include "kr_def.h"     /*  Default Values  */
  31.  
  32. #ifndef rand
  33. #include "random.h"     /*  Randomize Library Function Prototypes  */
  34. #endif
  35.  
  36. #include "kernel.ph"     /*  Function Prototypes  */
  37. #include "kr_mem.h"     /*  Function Prototypes  */
  38. #include "kr_funcs.h"     /*  Function Prototypes  */
  39. #include "kr_mac.h"     /*  Kernel Macros  */
  40. #include "cc_rcc_topo.h"
  41. #include "kr_newpattern.h"
  42.  
  43. #ifdef MASPAR_KERNEL
  44.  
  45. #include "kr_feedf.h"     /*  Function Prototypes */
  46.  
  47. #endif
  48.  
  49. #include "kr_art.h"      /*  Function Prototypes  */
  50. #include "kr_art1.h"     /*  Prototypes and global defs for ART1  */
  51. #include "kr_art2.h"     /*  Prototypes and global defs for ART2  */
  52. #include "kr_amap.h"     /*  Prototypes and global defs for ARTMAP  */
  53. #include "kr_JordElm.h"
  54.  
  55. /*****************************************************************************
  56.   FUNCTION : kr_countUnits
  57.  
  58.   PURPOSE  : count units according to their topological type 
  59.   NOTES    :
  60.  
  61.   RETURNS  :
  62.   UPDATE   : 
  63. ******************************************************************************/
  64. static void  kr_countUnits(struct Unit *unit_ptr, int mode)
  65. {
  66.   if (mode == UNIT_ADD)  {
  67.     /*  add unit  */
  68.     switch (unit_ptr->flags & UFLAG_TTYP_PAT)  {
  69.       case  UFLAG_TTYP_IN:
  70.         NoOfInputUnits++;
  71.         break;
  72.       case  UFLAG_TTYP_OUT:
  73.         NoOfOutputUnits++;
  74.         break;
  75.       case  UFLAG_TTYP_HIDD:
  76.         NoOfHiddenUnits++;
  77.         break;
  78.     }
  79.     return;
  80.   }
  81.   if (mode == UNIT_DELETE)  {
  82.     /*  delete unit  */
  83.     switch (unit_ptr->flags & UFLAG_TTYP_PAT)  {
  84.       case  UFLAG_TTYP_IN:
  85.         --NoOfInputUnits;
  86.         break;
  87.       case  UFLAG_TTYP_OUT:
  88.         --NoOfOutputUnits;
  89.         break;
  90.       case  UFLAG_TTYP_HIDD:
  91.         --NoOfHiddenUnits;
  92.         break;
  93.     }
  94.     return;
  95.   }
  96. }
  97.  
  98. /*****************************************************************************
  99.   FUNCTION : kr_symbolCheck 
  100.  
  101.   PURPOSE  : spell checker  (check identifiers for matching [A-Za-z]^[|, ]*
  102.   NOTES    :
  103.  
  104.   RETURNS  :
  105.   UPDATE   : 
  106. ******************************************************************************/
  107. bool    kr_symbolCheck(char *symbol)
  108. {
  109.   register  char  c;
  110.  
  111.  
  112.   KernelErrorCode = KRERR_SYMBOL;
  113.  
  114.   if (!isalpha( *symbol ))
  115.     /*    Symbol pattern invalid (must match [A-Za-z]^[|, ]*)  */
  116.     return( FALSE );
  117.  
  118.   while ( (c = *(++symbol)) != '\0' )
  119.     {
  120.     if (!isgraph( c ))
  121.       /*  Symbol pattern invalid (must match [A-Za-z]^[|, ]*)  */
  122.       return( FALSE );
  123.  
  124.     if ( c == '|' || c == ',')
  125.       /*  Symbol pattern invalid (must match [A-Za-z]^[|, ]*)  */
  126.       return( FALSE );
  127.   }
  128.  
  129.   KernelErrorCode = KRERR_NO_ERROR;
  130.   return( TRUE );
  131. }
  132.  
  133. /*****************************************************************************
  134.   FUNCTION : kr_getUnitPtr
  135.  
  136.   PURPOSE  : 
  137.   NOTES    :
  138.  
  139.   RETURNS  : returns the pointer to the given unit, returns NULL if unit 
  140.              doesn't exist
  141.   UPDATE   : 
  142. ******************************************************************************/
  143. struct Unit  *kr_getUnitPtr(int unit_no)
  144. {
  145.   struct Unit   *unit_ptr;
  146.  
  147.   KernelErrorCode = KRERR_NO_ERROR;
  148.  
  149.   if ((unit_no != 0) &&
  150.       (unit_no >= MinUnitNo) && (unit_no <= MaxUnitNo) &&
  151.       UNIT_IN_USE( unit_ptr = unit_array + unit_no ))
  152.     return( unit_ptr );
  153.  
  154.   /*  invalid unit no.  */
  155.   KernelErrorCode = KRERR_UNIT_NO;
  156.   return( NULL );
  157. }
  158.  
  159. /*****************************************************************************
  160.   FUNCTION : kr_getUnitValues
  161.  
  162.   PURPOSE  : 
  163.   NOTES    :
  164.  
  165.   RETURNS  : Returns the value of the specified unit component
  166.   UPDATE   : 
  167. ******************************************************************************/
  168. FlintType  kr_getUnitValues(int unit_no, int component_selector)
  169. {
  170.   struct Unit   *unit_ptr;
  171.  
  172.   unit_ptr = kr_getUnitPtr( unit_no );
  173.   if (KernelErrorCode != KRERR_NO_ERROR)
  174.     return( (FlintType) 0);    /*  invalid unit no.  */
  175.  
  176.   switch (component_selector)
  177.     {
  178.     case SEL_UNIT_ACT:
  179.       return( (FlintType) unit_ptr->act );
  180.     case SEL_UNIT_OUT:
  181.       return( (FlintType) unit_ptr->Out.output );
  182.     case SEL_UNIT_IACT:
  183.       return( (FlintType) unit_ptr->i_act );
  184.     case SEL_UNIT_BIAS:
  185.       return( (FlintType) unit_ptr->bias );
  186.     case SEL_UNIT_VALA: 
  187.       return( (FlintType) unit_ptr->value_a );
  188.     default:
  189.       KernelErrorCode = KRERR_PARAMETERS;
  190.       return ((FlintType) 0);    /*  invalid selector */
  191.   }
  192. }
  193. /*****************************************************************************
  194.   FUNCTION : kr_setUnitValues
  195.  
  196.   PURPOSE  : Sets the value of the specified unit component
  197.   NOTES    :
  198.  
  199.   RETURNS  : Returns the errorcode
  200.   UPDATE   : 
  201. ******************************************************************************/
  202. krui_err  kr_setUnitValues(int unit_no, int component_selector, 
  203.                FlintTypeParam value)
  204. {
  205.   struct Unit   *unit_ptr;
  206.  
  207.   unit_ptr = kr_getUnitPtr( unit_no );
  208.   if (KernelErrorCode != KRERR_NO_ERROR)
  209.     return( KernelErrorCode );      /*  invalid unit no.    */
  210.  
  211.   switch (component_selector)
  212.     {
  213.     case SEL_UNIT_ACT:
  214.       unit_ptr->act = (FlintType) value;
  215.       break;
  216.     case SEL_UNIT_OUT:
  217.       unit_ptr->Out.output = (FlintType) value;
  218.       break;
  219.     case SEL_UNIT_IACT:
  220.       unit_ptr->i_act = (FlintType) value;
  221.       break;
  222.     case SEL_UNIT_BIAS:
  223.       unit_ptr->bias = (FlintType) value;
  224.       break;
  225.     case SEL_UNIT_VALA: 
  226.       unit_ptr->value_a = (FlintType) value;
  227.       break;
  228.     default:
  229.       KernelErrorCode = KRERR_PARAMETERS;
  230.       break;   /*  invalid selector */
  231.   }
  232.  
  233.   return( KernelErrorCode );
  234. }
  235. /*****************************************************************************
  236.   FUNCTION : kr_setAllUnitValues
  237.  
  238.   PURPOSE  : Sets all unit components of the specified unit
  239.   NOTES    :
  240.  
  241.   RETURNS  : Returns the errorcode
  242.   UPDATE   : 
  243. ******************************************************************************/
  244. krui_err  kr_setAllUnitValues(int unit_no, FlintTypeParam out, 
  245.                   FlintTypeParam act, FlintTypeParam i_act, 
  246.                   FlintTypeParam bias)
  247. {
  248.   struct Unit   *unit_ptr;
  249.  
  250.   unit_ptr = kr_getUnitPtr( unit_no );
  251.   if (KernelErrorCode != KRERR_NO_ERROR)
  252.     return( KernelErrorCode );
  253.  
  254.   unit_ptr->Out.output = (FlintType) out;
  255.   unit_ptr->act = (FlintType) act;
  256.   unit_ptr->i_act = (FlintType) i_act;
  257.   unit_ptr->bias = (FlintType) bias;
  258.  
  259.   return( KernelErrorCode );
  260. }
  261.  
  262. /*****************************************************************************
  263.   FUNCTION : kr_makeDefaultUnit
  264.  
  265.   PURPOSE  : Creates a unit with default values
  266.   NOTES    :
  267.  
  268.   RETURNS  : 
  269.   UPDATE   : 
  270. ******************************************************************************/
  271. int  kr_makeDefaultUnit(void)
  272. {
  273.   struct Unit  *unit_ptr;
  274.   FunctionPtr  func_ptr;
  275.   int  unit_no;
  276.  
  277.  
  278.   unit_no = krm_getUnit();
  279.   if (KernelErrorCode != KRERR_NO_ERROR)
  280.     return( KernelErrorCode );
  281.  
  282.   (void) kr_setAllUnitValues( unit_no, (FlintTypeParam) DEF_OUT, DefaultIAct,
  283.                   DefaultIAct, DefaultBias );
  284.  
  285.   unit_ptr = unit_array + unit_no;
  286.  
  287.   unit_ptr->Ftype_entry = NULL;
  288.   unit_ptr->value_a = (FlintType) 0;          /*previous bias change*/
  289.   unit_ptr->value_b = (FlintType) 0;          /*previous bias slope*/
  290.   unit_ptr->value_c = (FlintType) 0;          /*actual bias slope*/
  291.  
  292.   if (DefaultUFuncAct == NULL)  {
  293.     if (!krf_funcSearch( krf_getCurrentNetworkFunc( ACT_FUNC ), 
  294.                          ACT_FUNC, &func_ptr))
  295.       return( KernelErrorCode );
  296.  
  297.     DefaultUFuncAct = (ActFuncPtr) func_ptr;
  298.  
  299.     if (!krf_funcSearch( krf_getCurrentNetworkFunc( ACT_FUNC ), 
  300.                          ACT_DERIV_FUNC, &func_ptr))
  301.       return( KernelErrorCode );
  302.  
  303.     DefaultUFuncActDeriv = (ActDerivFuncPtr) func_ptr;
  304.     
  305.     if (!krf_funcSearch( krf_getCurrentNetworkFunc( OUT_FUNC ), 
  306.                          OUT_FUNC, &func_ptr))
  307.       return( KernelErrorCode );
  308.  
  309.     DefaultUFuncOut = (OutFuncPtr) func_ptr;
  310.   }
  311.  
  312.   unit_ptr->out_func = DefaultUFuncOut;       /*  default output function  */
  313.   unit_ptr->act_func = DefaultUFuncAct;       /*  default activation function */
  314.   unit_ptr->act_deriv_func = DefaultUFuncActDeriv; /* def. derivation actfunc */
  315.   unit_ptr->unit_name= NULL;            /*  default is no unit name */
  316.   unit_ptr->subnet_no  = DefaultSubnetNo;
  317.   unit_ptr->layer_no   = DefaultLayerNo;
  318.   unit_ptr->unit_pos.x = DefaultPosX;
  319.   unit_ptr->unit_pos.y = DefaultPosY;
  320.  
  321. #ifdef KERNEL3D
  322.   unit_ptr->unit_pos.z = DefaultPosZ;
  323. #endif
  324.  
  325.   /*  set unit flags  */
  326.   unit_ptr->flags = UFLAG_INITIALIZED | DefaultSType;
  327.  
  328.   /*  count units  */
  329.   kr_countUnits( unit_ptr, UNIT_ADD );
  330.  
  331.   return( unit_no );
  332. }
  333.  
  334. /*****************************************************************************
  335.   FUNCTION : kr_createUnit
  336.  
  337.   PURPOSE  : Creates a user defined unit
  338.   NOTES    :
  339.  
  340.   RETURNS  : 
  341.   UPDATE   : 
  342. ******************************************************************************/
  343. int  kr_createUnit(char *unit_name, char *out_func_name, char *act_func_name, 
  344.            FlintTypeParam i_act, FlintTypeParam bias)
  345. {
  346.   FunctionPtr   out_func_ptr, act_func_ptr, act_deriv_func_ptr;
  347.   char  *str_ptr;
  348.   int   unit_no;
  349.   struct Unit  *unit_ptr;
  350.  
  351.  
  352.  
  353.   if (!kr_symbolCheck( unit_name ))
  354.     return( KernelErrorCode );    /*  Symbol pattern invalid 
  355.                     (must match [A-Za-z]^[|, ]*)  */
  356.  
  357.   if ( !krf_funcSearch( out_func_name, OUT_FUNC, &out_func_ptr ) )
  358.     return( KernelErrorCode );
  359.   if ( !krf_funcSearch( act_func_name, ACT_FUNC, &act_func_ptr ) )
  360.     return( KernelErrorCode );
  361.  
  362.   /*  set the derivation function of the activation function  */ 
  363.   if ( !krf_funcSearch( act_func_name, ACT_DERIV_FUNC, &act_deriv_func_ptr ))
  364.     return( KernelErrorCode );
  365.  
  366.   if ( (str_ptr = krm_NTableInsertSymbol( unit_name, UNIT_SYM ) ) == NULL)
  367.     return( KernelErrorCode );
  368.  
  369.   unit_no = kr_makeDefaultUnit();
  370.   if (KernelErrorCode != KRERR_NO_ERROR)
  371.     return( KernelErrorCode );
  372.  
  373.   (void) kr_setAllUnitValues( unit_no, (FlintTypeParam) DEF_OUT,
  374.                   i_act, i_act, bias );
  375.  
  376.   unit_ptr = unit_array + unit_no;
  377.  
  378.   unit_ptr->out_func  = (OutFuncPtr) out_func_ptr;
  379.   unit_ptr->act_func  = (ActFuncPtr) act_func_ptr;
  380.   unit_ptr->act_deriv_func = (ActDerivFuncPtr) act_deriv_func_ptr;
  381.   unit_ptr->unit_name = str_ptr;
  382.  
  383.   NetModified = TRUE;
  384.   return( unit_no );
  385. }
  386.  
  387. /*****************************************************************************
  388.   FUNCTION : kr_unitSetTType
  389.  
  390.   PURPOSE  : Sets the topologic type of the unit
  391.   NOTES    :
  392.  
  393.   RETURNS  : Returns the errorcode
  394.   UPDATE   : 
  395. ******************************************************************************/
  396. krui_err  kr_unitSetTType(int unit_no, int UnitTType)
  397. {
  398.   struct  Unit    *unit_ptr;
  399.   int  intflags;
  400.  
  401.   if ((unit_ptr = kr_getUnitPtr( unit_no )) == NULL)
  402.     return( KernelErrorCode );
  403.  
  404.   intflags = kr_TType2Flags( UnitTType );
  405.   if (KernelErrorCode != KRERR_NO_ERROR)
  406.     return( KernelErrorCode );
  407.  
  408.   if (((FlagWord) intflags == UFLAG_TTYP_SPEC_X) ||
  409.       ((FlagWord) intflags == UFLAG_TTYP_N_SPEC_X)) {
  410.       if ((FlagWord) intflags == UFLAG_TTYP_SPEC_X) {
  411.       /*  the topologic type of the unit will change  */
  412.       NetModified = TRUE;
  413.       /*  count units  */
  414.       kr_countUnits( unit_ptr, UNIT_DELETE );
  415.       
  416.       /*  change topologic type of the unit,  add special Flag  */
  417.       unit_ptr->flags |= (FlagWord)  UFLAG_TTYP_SPEC;
  418.       
  419.       /*  count units  */
  420.       kr_countUnits( unit_ptr, UNIT_ADD );
  421.       }else{
  422.       if((unit_ptr->flags & UFLAG_TTYP_PAT)!= UFLAG_TTYP_SPEC){ 
  423.           /*  the topologic type of the unit will change  */
  424.           NetModified = TRUE;
  425.           /*  count units  */
  426.           kr_countUnits( unit_ptr, UNIT_DELETE );
  427.  
  428.           /*  change topologic type of the unit,  delete special Flag  */
  429.           unit_ptr->flags &= (FlagWord)  ~UFLAG_TTYP_SPEC;
  430.       
  431.           /*  count units  */
  432.           kr_countUnits( unit_ptr, UNIT_ADD );
  433.       }
  434.       }
  435.   }else{
  436.       if ((unit_ptr->flags & UFLAG_TTYP_PAT) != (FlagWord) intflags) {  
  437.       /*  the topologic type of the unit will change  */
  438.       NetModified = TRUE;
  439.       /*  count units  */
  440.       kr_countUnits( unit_ptr, UNIT_DELETE );
  441.       
  442.       /*  change topologic type of the unit  */
  443.       unit_ptr->flags &= ~UFLAG_TTYP_PAT;
  444.       unit_ptr->flags |= (FlagWord)  intflags;
  445.       
  446.       /*  count units  */
  447.       kr_countUnits( unit_ptr, UNIT_ADD );
  448.       }
  449.   }
  450.  
  451.   return( KernelErrorCode );
  452. }
  453.  
  454.  
  455.  
  456. /*****************************************************************************
  457.   FUNCTION : kr_setSite
  458.  
  459.   PURPOSE  : initialize the first/next site or the named site at the current 
  460.              unit for access
  461.   NOTES    :
  462.  
  463.   RETURNS  : 
  464.   UPDATE   : 
  465. ******************************************************************************/
  466. int  kr_setSite(int mode, char *site_name)
  467. {
  468.   struct SiteTable  *stbl_ptr;
  469.  
  470.   if (unitPtr == NULL)  {
  471.     KernelErrorCode = KRERR_UNIT_NO;
  472.     return( KernelErrorCode );
  473.   }
  474.  
  475.   KernelErrorCode = KRERR_NO_ERROR;
  476.  
  477.   switch (mode)  {
  478.     case  FIRST:
  479.       prevSitePtr = NULL;
  480.  
  481.       if UNIT_HAS_SITES( unitPtr )
  482.     {  /*  Unit has sites  */
  483.     sitePtr = unitPtr->sites;
  484.     return( TRUE );
  485.       }
  486.       else  {
  487.     sitePtr = NULL;
  488.     return( FALSE );
  489.       }
  490.  
  491.     case  NEXT:
  492.       if ((sitePtr == NULL) || (sitePtr->next == NULL))  return( FALSE );
  493.  
  494.       prevSitePtr = sitePtr;
  495.       sitePtr      = sitePtr->next;
  496.       return( TRUE );
  497.  
  498.     case  NAME:
  499.       if (!UNIT_HAS_SITES( unitPtr ))
  500.     {  /*  Current unit doesn't have sites  */
  501.     KernelErrorCode = KRERR_NO_SITES;
  502.     return( KernelErrorCode );
  503.       }
  504.  
  505.       if ((stbl_ptr = krm_STableSymbolSearch( site_name )) == NULL)
  506.     {  /*    site name isn't defined */
  507.     KernelErrorCode = KRERR_UNDEF_SITE_NAME;
  508.     return( KernelErrorCode );
  509.       }
  510.  
  511.       for (sitePtr = unitPtr->sites, prevSitePtr = NULL;
  512.        sitePtr != NULL;
  513.        prevSitePtr = sitePtr, sitePtr = sitePtr->next)
  514.     if (sitePtr->site_table == stbl_ptr)
  515.       return( KRERR_NO_ERROR );  /*  site was found  */
  516.  
  517.       sitePtr = prevSitePtr = NULL;
  518.  
  519.       /*  Current unit doesn't have a site with this name  */
  520.       KernelErrorCode = KRERR_NO_SUCH_SITE;  
  521.       return( KernelErrorCode );
  522.  
  523.     default:
  524.       KernelErrorCode = KRERR_PARAMETERS;
  525.       return( KernelErrorCode );
  526.   }
  527. }
  528.  
  529.  
  530. /*****************************************************************************
  531.   FUNCTION : kr_getUnit
  532.  
  533.   PURPOSE  : returns the number of the first/next/current unit of the unit array
  534.   NOTES    :
  535.  
  536.   RETURNS  : 
  537.   UPDATE   : 
  538. ******************************************************************************/
  539. int  kr_getUnit(int mode)
  540. {
  541.   register struct Unit   *unit_ptr;
  542.  
  543.  
  544.   if (NoOfUnits == 0)  return( 0 );
  545.  
  546.   switch (mode)
  547.     {
  548.     case  FIRST:
  549.       unitNo = MinUnitNo;
  550.       unitPtr = unit_array + MinUnitNo;
  551.  
  552.       if UNIT_HAS_SITES( unitPtr )
  553.     {  /*  Initialize current site pointer to the first available site */
  554.     prevSitePtr = NULL;
  555.     sitePtr = unitPtr->sites;
  556.       }
  557.       else
  558.     {  /*  No sites available  */
  559.     prevSitePtr = NULL;
  560.     sitePtr     = NULL;
  561.       }
  562.  
  563.       return( unitNo );
  564.  
  565.     case  NEXT:
  566.       unit_ptr = unitPtr;
  567.       if ((unit_ptr - unit_array) >= MaxUnitNo)  return( 0 );
  568.  
  569.       while (!UNIT_IN_USE( ++unit_ptr )) ;
  570.  
  571.       unitNo = unit_ptr - unit_array;
  572.       unitPtr = unit_ptr;
  573.  
  574.       if UNIT_HAS_SITES( unit_ptr )
  575.     {  /*  Initialize current site pointer to the first available site */
  576.     prevSitePtr = NULL;
  577.     sitePtr = unit_ptr->sites;
  578.       }
  579.       else
  580.     {  /*  No sites available  */
  581.     prevSitePtr = NULL;
  582.     sitePtr     = NULL;
  583.       }
  584.  
  585.       return( unitNo );
  586.  
  587.     case  CURRENT:
  588.       return( unitNo );
  589.  
  590.     default:
  591.       KernelErrorCode = KRERR_PARAMETERS;
  592.       return( 0 );
  593.   }
  594. }
  595.  
  596. /*****************************************************************************
  597.   FUNCTION : kr_setCurrUnit
  598.  
  599.   PURPOSE  : initializes the given unit for access
  600.   NOTES    :
  601.  
  602.   RETURNS  : Returns the errorcode 
  603.   UPDATE   : 
  604. ******************************************************************************/
  605. krui_err  kr_setCurrUnit(int unit_no)
  606. {
  607.   struct Unit   *unit_ptr;
  608.  
  609.  
  610.   if ((unit_ptr = kr_getUnitPtr( unit_no )) == NULL)
  611.     return( KernelErrorCode );
  612.  
  613.   unitNo = unit_no;
  614.   unitPtr = unit_ptr;
  615.  
  616.   if UNIT_HAS_SITES( unit_ptr )
  617.     {  /*  Initialize current site pointer to the first available site */
  618.     prevSitePtr = NULL;
  619.     sitePtr = unit_ptr->sites;
  620.   }
  621.   else
  622.     {  /*  No sites available  */
  623.     prevSitePtr = NULL;
  624.     sitePtr    = NULL;
  625.   }
  626.  
  627.   return( KRERR_NO_ERROR );
  628. }
  629.  
  630.  
  631. /*****************************************************************************
  632.   FUNCTION : kr_getPredecessorUnit
  633.  
  634.   PURPOSE  : Returns the no. of first, next or current predecessor unit of the
  635.              current unit/site and the connection weight
  636.   NOTES    :
  637.  
  638.   RETURNS  : 
  639.   UPDATE   : 
  640. ******************************************************************************/
  641. int  kr_getPredecessorUnit(int mode, FlintType *weight)
  642. {
  643.   static struct Link  *link_ptr = NULL;
  644.  
  645.  
  646.   if (unitPtr == NULL)
  647.     {  /*  no current unit  */
  648.     KernelErrorCode = KRERR_NO_CURRENT_UNIT;
  649.     return( 0 );
  650.   }
  651.  
  652.   switch (mode)
  653.     {
  654.     case  FIRST:  /*  first predecessor link wanted  */
  655.       if UNIT_HAS_SITES( unitPtr )
  656.     {
  657.     if (sitePtr == NULL)
  658.       /*  site not initialized  */
  659.       link_ptr = unitPtr->sites->links;
  660.     else
  661.       link_ptr = sitePtr->links;
  662.       }
  663.       else
  664.     link_ptr = (struct Link *) unitPtr->sites;
  665.  
  666.       linkPtr = link_ptr;
  667.       prevLinkPtr = NULL;
  668.       if (link_ptr == NULL)  return( 0 );  /*  No inputs   */
  669.  
  670.       *weight = link_ptr->weight;
  671.       return( link_ptr->to - unit_array );  /*    Return unit number  */
  672.  
  673.     case  NEXT:
  674.       if (link_ptr == NULL)
  675.      {  /*    no current link  */
  676.      KernelErrorCode = KRERR_NO_CURRENT_LINK;
  677.      return( 0 );
  678.        }
  679.  
  680.       prevLinkPtr = link_ptr;
  681.       if ((linkPtr = link_ptr = link_ptr->next) == NULL)
  682.     {
  683.     prevLinkPtr = NULL;
  684.     return( 0 );  /*  no successor unit  */
  685.       }
  686.  
  687.  
  688.       *weight = link_ptr->weight;
  689.       return( link_ptr->to - unit_array );  /*    Return unit number  */
  690.  
  691.     case  CURRENT:
  692.       if (link_ptr == NULL)
  693.      {  /*    no current link  */
  694.      KernelErrorCode = KRERR_NO_CURRENT_LINK;
  695.      return( 0 );
  696.        }
  697.  
  698.       *weight = link_ptr->weight;
  699.       return( link_ptr->to - unit_array );  /*    Return unit number  */
  700.  
  701.     default:
  702.       KernelErrorCode = KRERR_PARAMETERS;
  703.       return( 0 );
  704.   }
  705. }
  706.  
  707. /*****************************************************************************
  708.   FUNCTION : kr_searchOutputConnection
  709.  
  710.   PURPOSE  :
  711.   NOTES    :
  712.  
  713.   RETURNS  : 
  714.   UPDATE   : 
  715. ******************************************************************************/
  716. static int  kr_searchOutputConnection(struct Unit *start_unit_ptr, 
  717.                       struct Unit *source_unit_ptr, 
  718.                       FlintType *weight)
  719. {
  720.   register struct  Link  *link_ptr, *prev_link_ptr;
  721.   register struct  Unit  *source_unit;
  722.   register struct  Site  *site_ptr, *prev_site_ptr;
  723.   register struct  Unit  *unit_ptr;
  724.  
  725.  
  726.   source_unit = source_unit_ptr;
  727.  
  728.   if ((sitePtr != NULL))
  729.     {  /*  current unit has sites, so search for another connection at the
  730.        other sites of the unit  */
  731.     for (site_ptr = sitePtr->next, prev_site_ptr = sitePtr;
  732.      site_ptr != NULL;
  733.      prev_site_ptr = site_ptr, site_ptr = site_ptr->next)
  734.       for (link_ptr = site_ptr->links, prev_link_ptr = NULL;
  735.        link_ptr != NULL;
  736.        prev_link_ptr = link_ptr, link_ptr = link_ptr->next)
  737.     if (link_ptr->to == source_unit)
  738.       {
  739.       sitePtr = site_ptr;  /*  set current site  */
  740.       prevSitePtr = prev_site_ptr;    /*  set previous site  */
  741.       linkPtr = link_ptr;  /*  set current link  */
  742.       prevLinkPtr = prev_link_ptr;    /*  set previous link  */
  743.  
  744.       *weight = link_ptr->weight;
  745.       return( unitNo );
  746.         }
  747.  
  748.     start_unit_ptr++;  /*  no connection found at the current site,
  749.                            so start search at the next units  */
  750.   }
  751.  
  752.   for(unit_ptr = start_unit_ptr; unit_ptr <= unit_array + MaxUnitNo; unit_ptr++)
  753.     if UNIT_IN_USE( unit_ptr )
  754.        {
  755.        if UNIT_HAS_DIRECT_INPUTS( unit_ptr )
  756.      {
  757.      for (link_ptr = (struct Link *) unit_ptr->sites, prev_link_ptr = NULL;
  758.           link_ptr != NULL;
  759.           prev_link_ptr = link_ptr, link_ptr = link_ptr->next)
  760.        if (link_ptr->to == source_unit)
  761.          {
  762.          unitPtr = unit_ptr;  /*  set current unit pointer    */
  763.          unitNo = unit_ptr - unit_array;  /*  set current unit no.    */
  764.          sitePtr = prevSitePtr = NULL;  /*    no current site  */
  765.          linkPtr = link_ptr;  /*  set current link    */
  766.          prevLinkPtr = prev_link_ptr;  /*  set previous link  */
  767.  
  768.          *weight = link_ptr->weight;
  769.          return( unitNo );
  770.        }
  771.        }
  772.        else
  773.      if UNIT_HAS_SITES( unit_ptr )
  774.        {
  775.        for (site_ptr = unit_ptr->sites, prev_site_ptr = NULL;
  776.         site_ptr != NULL;
  777.         prev_site_ptr = site_ptr, site_ptr = site_ptr->next)
  778.          for (link_ptr = site_ptr->links, prev_link_ptr = NULL;
  779.           link_ptr != NULL;
  780.           prev_link_ptr = link_ptr, link_ptr = link_ptr->next)
  781.            if (link_ptr->to == source_unit)
  782.          {
  783.          unitPtr = unit_ptr;  /*  set current unit pointer  */
  784.          unitNo = unit_ptr - unit_array;  /*  set current unit no.  */
  785.          sitePtr = site_ptr;  /*  set current site  */
  786.          prevSitePtr = prev_site_ptr;  /*  set previous site  */
  787.          linkPtr = link_ptr;  /*  set current link  */
  788.          prevLinkPtr = prev_link_ptr;  /*  set previous link  */
  789.  
  790.          *weight = link_ptr->weight;
  791.          return( unitNo );
  792.            }
  793.      }
  794.     }
  795.  
  796.   /*  no successor unit found  */
  797.   unitPtr = NULL; unitNo = 0;  /*  no current unit  */
  798.   sitePtr = prevSitePtr = NULL;  /*  no current site  */
  799.   linkPtr = prevLinkPtr = NULL;  /*  no current link  */
  800.  
  801.   return( 0 );
  802. }
  803.  
  804.  
  805. /*****************************************************************************
  806.   FUNCTION : kr_getSuccessorUnit
  807.  
  808.   PURPOSE  : Returns the no. of first or next succecessor unit of the
  809.              given unit and the connection strenght.
  810.              Sets the current unit/site.
  811.   NOTES    :
  812.  
  813.   RETURNS  : 
  814.   UPDATE   : 
  815. ******************************************************************************/
  816. int  kr_getSuccessorUnit(int mode, int source_unit_no, FlintType *weight)
  817. {
  818.   static struct Unit  *source_unit_ptr,
  819.               *current_unit_ptr = NULL;
  820.   static struct Site  *current_site_ptr = NULL;
  821.   int  unit_no;
  822.  
  823.  
  824.   switch (mode)
  825.     {
  826.     case  FIRST:  /*  first successor link wanted  */
  827.       if ((source_unit_ptr = kr_getUnitPtr( source_unit_no )) == NULL)
  828.     return( KernelErrorCode );
  829.  
  830.       sitePtr = NULL;  /*  no current Site  */
  831.       unit_no = kr_searchOutputConnection( unit_array + MinUnitNo,
  832.                        source_unit_ptr, weight );
  833.       current_unit_ptr = unitPtr;
  834.       current_site_ptr = sitePtr;
  835.  
  836.       return( unit_no );
  837.  
  838.     case  NEXT:  /*  next successor link wanted  */
  839.       if (current_unit_ptr == NULL)
  840.     {  /*  no current unit    */
  841.     KernelErrorCode = KRERR_NO_CURRENT_UNIT;
  842.     return( 0 );
  843.       }
  844.  
  845.       sitePtr = current_site_ptr;
  846.  
  847.       unit_no = kr_searchOutputConnection( current_unit_ptr + 1,
  848.                        source_unit_ptr, weight );
  849.       current_unit_ptr = unitPtr;
  850.       current_site_ptr = sitePtr;
  851.  
  852.       return( unit_no );
  853.  
  854.     default:
  855.       KernelErrorCode = KRERR_PARAMETERS;
  856.       return( 0 );
  857.   }
  858. }
  859.  
  860.  
  861.  
  862. /*****************************************************************************
  863.   FUNCTION : kr_areConnected
  864.  
  865.   PURPOSE  : True if there exists a connection between source unit 
  866.              <source_unit_no> and target unit <target_unit_no>, otherwise false.
  867.          If there exist a  connection between these units, kr_areConnected 
  868.          returns the connection strength also.
  869.   NOTES    : This function is slow (Units are backward chained only)
  870.   IMPORTANT: If there exist a connection, the current unit and site will be
  871.          set to the target unit/site.
  872.  
  873.   RETURNS  : Returns FALSE if unit doesn't exist.
  874.   UPDATE   : 
  875. ******************************************************************************/
  876. bool  kr_areConnected(int source_unit_no, int target_unit_no, FlintType *weight)
  877. {
  878.   register struct  Link  *link_ptr, *prev_link_ptr;
  879.   register struct  Unit  *source_unit_ptr;
  880.   register struct  Site  *site_ptr, *prev_site_ptr;
  881.   struct  Unit    *target_unit_ptr;
  882.  
  883.  
  884.   if ( (source_unit_ptr = kr_getUnitPtr( source_unit_no ) ) == NULL)
  885.     return( FALSE );    /*  invalid unit #  */
  886.   if ( (target_unit_ptr = kr_getUnitPtr( target_unit_no ) ) == NULL)
  887.     return( FALSE );    /*  invalid unit #  */
  888.  
  889.   if UNIT_HAS_DIRECT_INPUTS( target_unit_ptr )
  890.     {
  891.     for(link_ptr = (struct Link *) target_unit_ptr->sites, prev_link_ptr = NULL;
  892.      link_ptr != NULL;
  893.      prev_link_ptr = link_ptr, link_ptr = link_ptr->next)
  894.       if (link_ptr->to == source_unit_ptr)
  895.     {  /*  connection found  */
  896.     unitPtr = target_unit_ptr;  /*    set current unit pointer  */
  897.     unitNo = target_unit_no;  /*  set current unit no.  */
  898.     sitePtr = prevSitePtr = NULL;  /*  no current site  */
  899.     linkPtr = link_ptr;  /*  set current link  */
  900.     prevLinkPtr = prev_link_ptr;  /*  set previous link  */
  901.  
  902.     *weight = link_ptr->weight;
  903.     return( TRUE );
  904.       }
  905.   }
  906.   else
  907.     if UNIT_HAS_SITES( target_unit_ptr )
  908.       for (site_ptr = target_unit_ptr->sites, prev_site_ptr = NULL;
  909.        site_ptr != NULL;
  910.        prev_site_ptr = site_ptr, site_ptr = site_ptr->next)
  911.     for (link_ptr = site_ptr->links, prev_link_ptr = NULL;
  912.          link_ptr != NULL;
  913.          prev_link_ptr = link_ptr, link_ptr = link_ptr->next)
  914.       if (link_ptr->to == source_unit_ptr)
  915.         {  /*  connection found  */
  916.         unitPtr = target_unit_ptr;    /*  set current unit pointer  */
  917.         unitNo = target_unit_no;  /*  set current unit no.    */
  918.         sitePtr = site_ptr;  /*  set current site  */
  919.         prevSitePtr = prev_site_ptr;  /*  set previous site  */
  920.         linkPtr = link_ptr;  /*  set current link  */
  921.         prevLinkPtr = prev_link_ptr;  /*  set previous link  */
  922.  
  923.         *weight = link_ptr->weight;
  924.         return( TRUE );
  925.       }
  926.  
  927.   /*  no successor unit found  */
  928.   unitPtr = NULL; unitNo = 0;  /*  no current unit  */
  929.   sitePtr = prevSitePtr = NULL;  /*  no current site  */
  930.   linkPtr = prevLinkPtr = NULL;  /*  no current link  */
  931.  
  932.   return( FALSE );
  933. }
  934.  
  935. /*****************************************************************************
  936.   FUNCTION : kr_isConnected
  937.  
  938.   PURPOSE  : 
  939.   NOTES    : If there exists a connection between the two units, the current 
  940.              link is set to the link between the two units.
  941.   RETURNS  : True if there exists a connection between source unit 
  942.              <source_unit_no> and the current unit/site, otherwise false.
  943.   UPDATE   : 
  944. ******************************************************************************/
  945. bool  kr_isConnected(int source_unit_no, FlintType *weight)
  946. {
  947.   register struct  Link  *link_ptr, *prev_link_ptr;
  948.   register struct  Unit  *source_unit_ptr;
  949.   struct  Link    *start_link_ptr;
  950.  
  951.  
  952.   if (unitPtr == NULL)
  953.     {  /*  no current unit  */
  954.     KernelErrorCode = KRERR_NO_CURRENT_UNIT;
  955.     return( FALSE );
  956.   }
  957.   if ((source_unit_ptr = kr_getUnitPtr( source_unit_no ) ) == NULL)
  958.     return( FALSE );  /*  invalid unit #  */
  959.  
  960.   if UNIT_HAS_DIRECT_INPUTS( unitPtr )
  961.     start_link_ptr = (struct Link *) unitPtr->sites;
  962.   else
  963.     if UNIT_HAS_SITES( unitPtr )
  964.       start_link_ptr = sitePtr->links;
  965.     else
  966.       return( FALSE );
  967.  
  968.   for (link_ptr = start_link_ptr, prev_link_ptr = NULL;
  969.        link_ptr != NULL;
  970.        prev_link_ptr = link_ptr, link_ptr = link_ptr->next)
  971.     if (link_ptr->to == source_unit_ptr)
  972.       {  /*  connection found  */
  973.       linkPtr = link_ptr;  /*  set current link  */
  974.       prevLinkPtr = prev_link_ptr;  /*    set previous link  */
  975.  
  976.       *weight = link_ptr->weight;
  977.       return( TRUE );
  978.     }
  979.  
  980.   /*  no successor unit found  */
  981.   linkPtr = prevLinkPtr = NULL;  /*  no current link  */
  982.  
  983.   return( FALSE );
  984. }
  985.  
  986.  
  987. /*****************************************************************************
  988.   FUNCTION : kr_getLinkWeight
  989.  
  990.   PURPOSE  : 
  991.   NOTES    : 
  992.  
  993.   RETURNS  : Returns the link weight of the current link
  994.   UPDATE   : 
  995. ******************************************************************************/
  996. FlintType  kr_getLinkWeight(void)
  997. {
  998.   if (linkPtr != NULL)    return( linkPtr->weight );
  999.  
  1000.   KernelErrorCode = KRERR_NO_CURRENT_LINK;
  1001.   return( (FlintType) 0 );
  1002. }
  1003.  
  1004.  
  1005. /*****************************************************************************
  1006.   FUNCTION : kr_setLinkWeight
  1007.  
  1008.   PURPOSE  : Sets the link weight of the current link
  1009.   NOTES    : 
  1010.  
  1011.   RETURNS  : 
  1012.   UPDATE   : 
  1013. ******************************************************************************/
  1014. void  kr_setLinkWeight(FlintTypeParam weight)
  1015. {
  1016.   if (linkPtr != NULL)
  1017.     {
  1018.     linkPtr->weight = weight;
  1019.     return;
  1020.   }
  1021.  
  1022.   KernelErrorCode = KRERR_NO_CURRENT_LINK;
  1023. }
  1024.  
  1025.  
  1026. /*****************************************************************************
  1027.   FUNCTION : kr_createLink 
  1028.  
  1029.   PURPOSE  : Creates a link between source unit and the current unit/site 
  1030.   NOTES    : kr_createLink DO NOT set the current link
  1031.              If you want to create a link and its unknown if there exists 
  1032.          already a connection between the two units, use krui_createLink 
  1033.          and test the return code, instead of the sequence kr_isConnected 
  1034.          and kr_createLink
  1035.   RETURNS  : Returns an error code:
  1036.              - if memory allocation fails
  1037.              - if source unit doesn't exist or
  1038.              - if there exists already a connection between current unit/site 
  1039.          and the source unit
  1040.              0 otherwise.    
  1041.   UPDATE   : 
  1042. ******************************************************************************/
  1043. krui_err  kr_createLink(int source_unit_no, FlintTypeParam weight)
  1044. {
  1045.   register struct Link    *link_ptr;
  1046.   register struct Unit    *source_unit_ptr;
  1047.  
  1048.  
  1049.   KernelErrorCode = KRERR_NO_ERROR;
  1050.  
  1051.   if (unitPtr == NULL)
  1052.     {  /*  no current unit  */
  1053.     KernelErrorCode = KRERR_NO_CURRENT_UNIT;
  1054.     return( KernelErrorCode );
  1055.   }
  1056.  
  1057.   if ((source_unit_ptr = kr_getUnitPtr( source_unit_no ) ) == NULL)
  1058.     return( KernelErrorCode );    /*  invalid unit #  */
  1059.  
  1060.   switch ((int) (unitPtr->flags & UFLAG_INPUT_PAT))
  1061.     {
  1062.     case  UFLAG_NO_INP:  /*  current unit doesn't have inputs  */
  1063.       if ((link_ptr = krm_getLink()) == NULL)
  1064.     return( KernelErrorCode );
  1065.  
  1066.       link_ptr->to     = source_unit_ptr;
  1067.       link_ptr->weight = (FlintType) weight;
  1068.       link_ptr->next   = NULL;
  1069.  
  1070.       unitPtr->sites = (struct Site *) link_ptr;
  1071.       unitPtr->flags |= UFLAG_DLINKS;  /*  unit has direkt inputs now  */
  1072.  
  1073.       break;
  1074.  
  1075.     case  UFLAG_DLINKS:  /*  current unit has direct inputs  */
  1076.       FOR_ALL_LINKS( unitPtr, link_ptr )
  1077.     if (link_ptr->to == source_unit_ptr)
  1078.       {  /*  there exists already a connection  */
  1079.       KernelErrorCode = KRERR_ALREADY_CONNECTED;
  1080.       return( KRERR_ALREADY_CONNECTED );
  1081.     }
  1082.  
  1083.       if ((link_ptr = krm_getLink()) == NULL)
  1084.     return( KernelErrorCode );
  1085.  
  1086.       link_ptr->to     = source_unit_ptr;
  1087.       link_ptr->weight = (FlintType) weight;
  1088.       link_ptr->next   = (struct Link *) unitPtr->sites;
  1089.       unitPtr->sites   = (struct Site *) link_ptr;
  1090.  
  1091.       break;
  1092.  
  1093.     case  UFLAG_SITES:    /*  current unit has sites  */
  1094.       FOR_ALL_LINKS_AT_SITE( sitePtr, link_ptr )
  1095.     if (link_ptr->to == source_unit_ptr)
  1096.       {  /*  there exists already a connection  */
  1097.       KernelErrorCode = KRERR_ALREADY_CONNECTED;
  1098.       return( KRERR_ALREADY_CONNECTED );
  1099.     }
  1100.  
  1101.       if ((link_ptr = krm_getLink()) == NULL)
  1102.     return( KernelErrorCode );
  1103.  
  1104.       link_ptr->to     = source_unit_ptr;
  1105.       link_ptr->weight = (FlintType) weight;
  1106.       link_ptr->next   = (struct Link *) sitePtr->links;
  1107.       sitePtr->links   = link_ptr;
  1108.  
  1109.       break;
  1110.  
  1111.     default:
  1112.       KernelErrorCode = KRERR_PARAMETERS;
  1113.       return( KernelErrorCode );
  1114.   }
  1115.  
  1116.   NetModified = TRUE;
  1117.   return( KRERR_NO_ERROR );
  1118. }
  1119.  
  1120.  
  1121. /*****************************************************************************
  1122.   FUNCTION : kr_deleteLink 
  1123.  
  1124.   PURPOSE  : Deletes the current link
  1125.   NOTES    : To delete a link between the current unit/site and the source unit
  1126.              <source_unit_no>, call krui_isConnected( source_unit_no ) and
  1127.              krui_deleteLink()
  1128.  
  1129.   RETURNS  : Returns the errorcode
  1130.   UPDATE   : 
  1131. ******************************************************************************/
  1132. krui_err  kr_deleteLink(void)
  1133. {
  1134.   register struct Link     *next_link_ptr;
  1135.  
  1136.  
  1137.   if (linkPtr == NULL)
  1138.     {  /*  no current link  */
  1139.     KernelErrorCode = KRERR_NO_CURRENT_LINK;
  1140.     return( KernelErrorCode );
  1141.   }
  1142.  
  1143.   if (unitPtr == NULL)
  1144.     {  /*  no current unit  */
  1145.     KernelErrorCode = KRERR_NO_CURRENT_UNIT;
  1146.     return( KernelErrorCode );
  1147.   }
  1148.  
  1149.   KernelErrorCode = KRERR_NO_ERROR;
  1150.   switch ((int) (unitPtr->flags & UFLAG_INPUT_PAT))
  1151.     {
  1152.     case  UFLAG_NO_INP:  /*  current unit doesn't have inputs  */
  1153.       KernelErrorCode = KRERR_UNIT_NO_INPUTS;
  1154.       return( KernelErrorCode );
  1155.  
  1156.     case  UFLAG_DLINKS:  /*  current unit has direct inputs  */
  1157.       next_link_ptr = linkPtr->next;
  1158.       krm_releaseLink( linkPtr );
  1159.       linkPtr = next_link_ptr;
  1160.  
  1161.       if (prevLinkPtr != NULL)    /*  current link isn't first link at the unit */
  1162.     prevLinkPtr->next = next_link_ptr;  /*    chain previous link pointer
  1163.                         with next link pointer    */
  1164.       else
  1165.     {  /*  current link is the first link at the unit  */
  1166.     unitPtr->sites = (struct Site *) next_link_ptr;
  1167.     if (next_link_ptr == NULL)
  1168.       unitPtr->flags &= (~UFLAG_INPUT_PAT);  /* last input deleted: 
  1169.                             the unit has no inputs now*/
  1170.       }
  1171.  
  1172.       NetModified = TRUE;
  1173.       return( KRERR_NO_ERROR );
  1174.  
  1175.     case  UFLAG_SITES:    /*  current unit has sites  */
  1176.       next_link_ptr = linkPtr->next;
  1177.       krm_releaseLink( linkPtr );
  1178.       linkPtr = next_link_ptr;
  1179.  
  1180.       if (prevLinkPtr != NULL)    /*  current link isn't first link at the unit */
  1181.     prevLinkPtr->next = next_link_ptr;  /*    chain previous link pointer
  1182.                         with next link pointer    */
  1183.       else  /*    current link is the first link at the unit  */
  1184.     sitePtr->links = next_link_ptr;
  1185.  
  1186.       NetModified = TRUE;
  1187.       return( KRERR_NO_ERROR );
  1188.    }
  1189.  
  1190.   KernelErrorCode = KRERR_PARAMETERS;
  1191.   return( KernelErrorCode );
  1192. }
  1193.  
  1194.  
  1195. /*****************************************************************************
  1196.   FUNCTION : kr_deleteAllLinks
  1197.  
  1198.   PURPOSE  : Deletes all input links at current unit/site
  1199.   NOTES    : 
  1200.  
  1201.   RETURNS  : Returns the errorcode
  1202.   UPDATE   : 
  1203. ******************************************************************************/
  1204. krui_err  kr_deleteAllLinks(int mode)
  1205. {
  1206.   if (unitPtr == NULL)
  1207.     {  /*  no current unit  */
  1208.     KernelErrorCode = KRERR_NO_CURRENT_UNIT;
  1209.     return( KernelErrorCode );
  1210.   }
  1211.  
  1212.   linkPtr = NULL;
  1213.   NetModified = TRUE;
  1214.  
  1215.   switch (mode)
  1216.     {
  1217.     case  INPUTS:  /*  delete all inputs  */
  1218.       if UNIT_HAS_DIRECT_INPUTS( unitPtr )
  1219.     {
  1220.     krm_releaseAllLinks( (struct Link *) unitPtr->sites );
  1221.     unitPtr->sites = NULL;
  1222.     unitPtr->flags &= (~UFLAG_INPUT_PAT);  /*  unit don't has inputs now  */
  1223.  
  1224.     return( KernelErrorCode );
  1225.       }
  1226.  
  1227.       if UNIT_HAS_SITES( unitPtr )
  1228.     {
  1229.     krm_releaseAllLinks( sitePtr->links );
  1230.     sitePtr->links = NULL;    /*  site has no inputs now   */
  1231.  
  1232.     return( KernelErrorCode );
  1233.       }
  1234.  
  1235.       return( KernelErrorCode );
  1236.  
  1237.     case  OUTPUTS:  /*    delete all outputs  */
  1238.       kr_deleteAllOutputLinks( unitPtr );
  1239.  
  1240.       return( KernelErrorCode );
  1241.   }
  1242.  
  1243.   KernelErrorCode = KRERR_PARAMETERS;
  1244.   return( KernelErrorCode );
  1245. }
  1246.  
  1247.  
  1248.  
  1249.  
  1250.  
  1251.  
  1252.  
  1253.  
  1254. /*#################################################
  1255.  
  1256. GROUP: Low-Level Kernel Functions
  1257.  
  1258. #################################################*/
  1259.  
  1260.  
  1261. /*****************************************************************************
  1262.   FUNCTION : kr_deleteAllInputs
  1263.  
  1264.   PURPOSE  : delete all links and sites at the given unit
  1265.   NOTES    : 
  1266.  
  1267.   RETURNS  : 
  1268.   UPDATE   : 
  1269. ******************************************************************************/
  1270. void    kr_deleteAllInputs(struct Unit *unit_ptr)
  1271. {
  1272.   register struct Site    *site_ptr;
  1273.  
  1274.  
  1275.   if (UNIT_HAS_SITES( unit_ptr ))
  1276.     {   /*  Unit has sites  */
  1277.     FOR_ALL_SITES( unit_ptr, site_ptr )
  1278.       /*  Release all links   */
  1279.       krm_releaseAllLinks( site_ptr->links );
  1280.  
  1281.     krm_releaseAllSites( unit_ptr->sites );
  1282.   }
  1283.   else
  1284.     {   /*  Unit don't has sites   */
  1285.     if (UNIT_HAS_DIRECT_INPUTS( unit_ptr ))
  1286.       krm_releaseAllLinks( (struct Link *) unit_ptr->sites );
  1287.   }
  1288.  
  1289.   unit_ptr->sites = NULL;
  1290.  
  1291.   /*  The unit has no inputs now  */
  1292.   unit_ptr->flags &= (~UFLAG_INPUT_PAT);
  1293. }
  1294.  
  1295. /*****************************************************************************
  1296.   FUNCTION : kr_deleteAllOutputLinks
  1297.  
  1298.   PURPOSE  : Deletes all output links at <source_unit>
  1299.   NOTES    : This function is slow
  1300.  
  1301.   RETURNS  : 
  1302.   UPDATE   : 
  1303. ******************************************************************************/
  1304. void  kr_deleteAllOutputLinks(struct Unit *source_unit_ptr)
  1305. {
  1306.   register struct Link   *link_ptr,
  1307.                          *pred_link_ptr;
  1308.   register struct Site   *site_ptr;
  1309.   register struct Unit   *unit_ptr;
  1310.  
  1311.  
  1312.   FOR_ALL_UNITS( unit_ptr )
  1313.     if UNIT_IN_USE( unit_ptr )
  1314.       if UNIT_HAS_SITES( unit_ptr )
  1315.         {  /*  unit has sites  */
  1316.     FOR_ALL_SITES( unit_ptr, site_ptr )
  1317.           for (link_ptr = site_ptr->links, pred_link_ptr = NULL;
  1318.                link_ptr != NULL;
  1319.                pred_link_ptr = link_ptr, link_ptr = link_ptr->next)
  1320.  
  1321.             if (link_ptr->to == source_unit_ptr)
  1322.               {     /*  Connection between unit and source_unit found   */
  1323.               if (pred_link_ptr == NULL)
  1324.                 site_ptr->links = link_ptr->next;
  1325.               else
  1326.                 pred_link_ptr->next = link_ptr->next;
  1327.  
  1328.               krm_releaseLink( link_ptr );
  1329.  
  1330.               break;    /*  next site/unit  */
  1331.         }
  1332.       }
  1333.       else  /*    unit has no sites   */
  1334.     if UNIT_HAS_DIRECT_INPUTS( unit_ptr )
  1335.           for (link_ptr = (struct Link *) unit_ptr->sites, pred_link_ptr = NULL;
  1336.                link_ptr != NULL;
  1337.                pred_link_ptr = link_ptr, link_ptr = link_ptr->next)
  1338.             if (link_ptr->to == source_unit_ptr)
  1339.               {     /*  Connection between unit and source_unit found   */
  1340.               if (pred_link_ptr == NULL)
  1341.                 {
  1342.                 unit_ptr->sites = (struct Site *) link_ptr->next;
  1343.                 if (link_ptr->next == NULL)
  1344.                   /*  The unit has no inputs now  */
  1345.                   unit_ptr->flags &= (~UFLAG_INPUT_PAT);
  1346.           }
  1347.               else
  1348.                 pred_link_ptr->next = link_ptr->next;
  1349.  
  1350.               krm_releaseLink( link_ptr );
  1351.  
  1352.               break;    /*  next unit  */
  1353.         }
  1354. }
  1355.  
  1356.  
  1357. /*****************************************************************************
  1358.   FUNCTION : kr_copyOutputLinks
  1359.  
  1360.   PURPOSE  : Copies all output links at <source_unit> to <new_unit>.
  1361.   NOTES    : This function is slow
  1362.  
  1363.   RETURNS  : Returns error code if memory allocation fails.
  1364.   UPDATE   : 
  1365. ******************************************************************************/
  1366. static krui_err  kr_copyOutputLinks(struct Unit *source_unit_ptr, 
  1367.                     struct Unit *new_unit_ptr)
  1368. {
  1369.   register struct Link   *link_ptr,
  1370.              *new_link;
  1371.   register struct Site   *site_ptr;
  1372.   register struct Unit   *unit_ptr;
  1373.  
  1374.  
  1375.   KernelErrorCode = KRERR_NO_ERROR;
  1376.  
  1377.   FOR_ALL_UNITS( unit_ptr )
  1378.     if UNIT_IN_USE( unit_ptr )
  1379.       if UNIT_HAS_DIRECT_INPUTS( unit_ptr )
  1380.     {
  1381.     FOR_ALL_LINKS( unit_ptr, link_ptr )
  1382.       if (link_ptr->to == source_unit_ptr)
  1383.         {  /*  Connection between unit and source_unit found   */
  1384.         if ( (new_link = krm_getLink() ) == NULL)
  1385.           return( KernelErrorCode );
  1386.  
  1387.         memcpy( (char *) new_link, (char *) link_ptr, LINK_SIZE );
  1388.         new_link->next = (struct Link *) unit_ptr->sites;
  1389.         unit_ptr->sites = (struct Site *) new_link;
  1390.  
  1391.         new_link->to = new_unit_ptr;
  1392.         new_link->weight = link_ptr->weight;
  1393.  
  1394.         break;    /*  next unit  */
  1395.       }
  1396.       }
  1397.       else
  1398.     if UNIT_HAS_SITES( unit_ptr )
  1399.       FOR_ALL_SITES_AND_LINKS( unit_ptr, site_ptr, link_ptr )
  1400.         if (link_ptr->to == source_unit_ptr)
  1401.           {  /*  Connection between unit and source_unit found   */
  1402.           if ( (new_link = krm_getLink() ) == NULL)
  1403.         return( KernelErrorCode );
  1404.  
  1405.           new_link->next = site_ptr->links;
  1406.           site_ptr->links = new_link;
  1407.  
  1408.           new_link->to = new_unit_ptr;
  1409.           new_link->weight = link_ptr->weight;
  1410.  
  1411.           break;    /*  next site/unit  */
  1412.         }
  1413.  
  1414.   return( KernelErrorCode );
  1415. }
  1416.  
  1417. /*****************************************************************************
  1418.   FUNCTION : kr_copyInputLinks
  1419.  
  1420.   PURPOSE  : Copy all input links from <source_unit> to <new_unit>
  1421.   NOTES    : 
  1422.  
  1423.   RETURNS  : Returns error code 
  1424.   UPDATE   : 
  1425. ******************************************************************************/
  1426. static krui_err  kr_copyInputLinks(struct Unit *source_unit_ptr, 
  1427.                    struct Unit *new_unit_ptr)
  1428. {
  1429.   register struct Link     *link_ptr, *new_link,
  1430.              *last_link_ptr;
  1431.   register struct Site     *source_site_ptr, *dest_site_ptr;
  1432.  
  1433.  
  1434.   KernelErrorCode = KRERR_NO_ERROR;
  1435.  
  1436.   if UNIT_HAS_DIRECT_INPUTS( source_unit_ptr )
  1437.     {
  1438.     last_link_ptr = new_link = NULL;
  1439.     FOR_ALL_LINKS( source_unit_ptr, link_ptr )
  1440.       {
  1441.       if ((new_link = krm_getLink()) == NULL)
  1442.     {
  1443.     new_unit_ptr->sites = (struct Site *) last_link_ptr;
  1444.     return( KernelErrorCode );
  1445.       }
  1446.  
  1447.       memcpy( (char *) new_link, (char *) link_ptr, LINK_SIZE );
  1448.       new_link->next = last_link_ptr;
  1449.       last_link_ptr = new_link;
  1450.     }
  1451.  
  1452.     new_unit_ptr->sites = (struct Site *) new_link;
  1453.     new_unit_ptr->flags &= ~UFLAG_INPUT_PAT;
  1454.     if (new_link != NULL)  new_unit_ptr->flags |= UFLAG_DLINKS;
  1455.   }
  1456.   else
  1457.     if UNIT_HAS_SITES( source_unit_ptr )
  1458.       FOR_ALL_SITES( source_unit_ptr, source_site_ptr )
  1459.     FOR_ALL_SITES( new_unit_ptr, dest_site_ptr )
  1460.       if (source_site_ptr->site_table == dest_site_ptr->site_table)
  1461.         {
  1462.         last_link_ptr = new_link = NULL;
  1463.         FOR_ALL_LINKS_AT_SITE( source_site_ptr, link_ptr )
  1464.           {
  1465.           if ((new_link = krm_getLink()) == NULL)
  1466.         {
  1467.         dest_site_ptr->links = last_link_ptr;
  1468.         return( KernelErrorCode );
  1469.           }
  1470.  
  1471.           memcpy( (char *) new_link, (char *) link_ptr, LINK_SIZE );
  1472.           new_link->next = last_link_ptr;
  1473.           last_link_ptr = new_link;
  1474.           }
  1475.  
  1476.         dest_site_ptr->links = new_link;
  1477.       }
  1478.  
  1479.   return( KernelErrorCode );
  1480. }
  1481.  
  1482.  
  1483.  
  1484.  
  1485. /*#################################################
  1486.  
  1487. GROUP: Site Name/Func functions
  1488.  
  1489. #################################################*/
  1490.  
  1491. /*****************************************************************************
  1492.   FUNCTION : kr_searchUnitSite
  1493.  
  1494.   PURPOSE  : search for a site at a unit
  1495.   NOTES    : 
  1496.  
  1497.   RETURNS  : Returns the site or NULL
  1498.   UPDATE   : 
  1499. ******************************************************************************/
  1500. struct Site *kr_searchUnitSite(struct Unit *unit_ptr,struct SiteTable *stbl_ptr)
  1501. {
  1502.   register struct Site    *site_ptr;
  1503.  
  1504.   FOR_ALL_SITES( unit_ptr, site_ptr )
  1505.     if (site_ptr->site_table == stbl_ptr)
  1506.       return( site_ptr );
  1507.  
  1508.   return( NULL );   /*  there is no site at this unit with this name    */
  1509. }
  1510.  
  1511.  
  1512. /*****************************************************************************
  1513.   FUNCTION : kr_searchNetSite
  1514.  
  1515.   PURPOSE  : searches for a site in the network
  1516.   NOTES    : 
  1517.  
  1518.   RETURNS  : 
  1519.   UPDATE   : 
  1520. ******************************************************************************/
  1521. int  kr_searchNetSite(struct SiteTable *stbl_ptr)
  1522. {
  1523.   register struct Site   *site_ptr;
  1524.   register struct Unit   *unit_ptr;
  1525.  
  1526.  
  1527.   if (NoOfUnits == 0)
  1528.     return( 0 ); /*  no units -> no sites */
  1529.  
  1530.   FOR_ALL_UNITS( unit_ptr )
  1531.     if (UNIT_HAS_SITES( unit_ptr ) && UNIT_IN_USE( unit_ptr ))
  1532.       {  /*  unit has sites and is in use  */
  1533.       FOR_ALL_SITES( unit_ptr, site_ptr )
  1534.         if (site_ptr->site_table == stbl_ptr)
  1535.           return( unit_ptr - unit_array );  /*  return unit no. */
  1536.     }
  1537.  
  1538.   return( 0 );  /*  site isn't in use   */
  1539. }
  1540.  
  1541.  
  1542. /*#################################################
  1543.  
  1544. GROUP: Link Functions
  1545.  
  1546. #################################################*/
  1547. /*****************************************************************************
  1548.   FUNCTION : kr_jogWeights
  1549.  
  1550.   PURPOSE  : Add random uniform distributed values to connection weights.
  1551.              <minus> must be less then <plus>.
  1552.   NOTES    : 
  1553.  
  1554.   RETURNS  : 
  1555.   UPDATE   : 
  1556. ******************************************************************************/
  1557. void  kr_jogWeights(FlintTypeParam minus, FlintTypeParam plus)
  1558. {
  1559.   register  struct Link   *link_ptr;
  1560.   FlagWord    flags;
  1561.   struct Unit   *unit_ptr;
  1562.   struct Site   *site_ptr;
  1563.   register FlintType  range, min;
  1564.  
  1565.  
  1566.   if (NoOfUnits == 0)  return;  /*  no. units  */
  1567.   range = plus - minus;
  1568.   min = minus;
  1569.  
  1570.   FOR_ALL_UNITS( unit_ptr )  {
  1571.       flags = unit_ptr->flags;
  1572.       
  1573.       if(((flags & UFLAG_IN_USE) == UFLAG_IN_USE) 
  1574.       && !IS_SPECIAL_UNIT(unit_ptr)){
  1575.       /*  unit is in use  */
  1576.       if (flags & UFLAG_DLINKS)
  1577.           /*  unit has direct links   */
  1578.           FOR_ALL_LINKS( unit_ptr, link_ptr )
  1579.           link_ptr->weight += (FlintType) drand48() * range + min;
  1580.       }else{
  1581.       if (flags & UFLAG_SITES)
  1582.           /*  unit has sites  */
  1583.           FOR_ALL_SITES_AND_LINKS( unit_ptr, site_ptr, link_ptr )
  1584.           link_ptr->weight += (FlintType) drand48() * range + min;
  1585.       }
  1586.   }
  1587. }
  1588.  
  1589.  
  1590.  
  1591. /*#################################################
  1592.  
  1593. GROUP: Site Functions
  1594.  
  1595. #################################################*/
  1596. /*****************************************************************************
  1597.   FUNCTION : kr_createDefaultSite
  1598.  
  1599.   PURPOSE  : Creates a new site with default initialisation
  1600.   NOTES    : 
  1601.  
  1602.   RETURNS  : the new site 
  1603.   UPDATE   : 
  1604. ******************************************************************************/
  1605. struct Site  *kr_createDefaultSite(void)
  1606. {
  1607.   struct Site   *site_ptr;
  1608.  
  1609.  
  1610.   if ( (site_ptr = krm_getSite() ) == NULL)   return( NULL );
  1611.  
  1612.   site_ptr->links = NULL;
  1613.   site_ptr->next  = NULL;
  1614.  
  1615.   return( site_ptr );
  1616. }
  1617.  
  1618.  
  1619.  
  1620. /*#################################################
  1621.  
  1622. GROUP: Unit Functions
  1623.  
  1624. #################################################*/
  1625.  
  1626.  
  1627. /*****************************************************************************
  1628.   FUNCTION : kr_unitNameSearch
  1629.  
  1630.   PURPOSE  : Searches for a unit with the given symbol pointer.
  1631.   NOTES    : 
  1632.  
  1633.   RETURNS  : Returns the first unit no. if a unit with the given name was found,
  1634.              0 otherwise
  1635.  
  1636.   UPDATE   : 
  1637. ******************************************************************************/
  1638. int  kr_unitNameSearch(int min_unit_no, char *unit_symbol_ptr)
  1639. {
  1640.   register char   *symbol;
  1641.   register struct Unit   *unit_ptr;
  1642.  
  1643.  
  1644.   if ((symbol = unit_symbol_ptr) == NULL)
  1645.     return( 0 );
  1646.  
  1647.   /*  search for symbol pointer  */
  1648.   for (unit_ptr = unit_array + min_unit_no; unit_ptr <= unit_array + MaxUnitNo; unit_ptr++)
  1649.     if UNIT_IN_USE( unit_ptr )
  1650.       if (unit_ptr->unit_name == symbol)
  1651.         return( unit_ptr - unit_array );
  1652.  
  1653.   return( 0 );
  1654. }
  1655.  
  1656. /*****************************************************************************
  1657.   FUNCTION : kr_copyUnitFrame
  1658.  
  1659.   PURPOSE  : copy the source unit with sites, but no links
  1660.   NOTES    : 
  1661.  
  1662.   RETURNS  : Returns the error code 
  1663.   UPDATE   : 
  1664. ******************************************************************************/
  1665. static krui_err kr_copyUnitFrame(struct Unit *source_unit_ptr, 
  1666.                  struct Unit *new_unit_ptr)
  1667. {
  1668.   struct Site    *site_ptr,
  1669.         *new_site_ptr,
  1670.         *last_site_ptr;
  1671.  
  1672.  
  1673.   KernelErrorCode = KRERR_NO_ERROR;
  1674.  
  1675.   memcpy( (char *) new_unit_ptr, (char *) source_unit_ptr, UNIT_SIZE );
  1676.  
  1677.   if (source_unit_ptr->unit_name != NULL)
  1678.     (void) krm_NTableInsertSymbol( source_unit_ptr->unit_name, UNIT_SYM );
  1679.  
  1680.   /*  unit has no inputs now  */
  1681.   new_unit_ptr->flags &= ~UFLAG_INPUT_PAT;
  1682.   new_unit_ptr->sites = NULL;
  1683.  
  1684.   if UNIT_HAS_SITES( source_unit_ptr )
  1685.     {  /*  Copy all sites, but no links.  */
  1686.     last_site_ptr = new_site_ptr = NULL;
  1687.     FOR_ALL_SITES( source_unit_ptr, site_ptr )  {
  1688.       if ((new_site_ptr = krm_getSite()) == NULL)  {
  1689.     new_unit_ptr->sites = last_site_ptr;
  1690.     return( KernelErrorCode );
  1691.       }
  1692.  
  1693.       memcpy( (char *) new_site_ptr, (char *) site_ptr, SITE_SIZE );
  1694.       new_site_ptr->links = NULL;
  1695.       new_site_ptr->next = last_site_ptr;
  1696.       last_site_ptr = new_site_ptr;
  1697.     }
  1698.  
  1699.     new_unit_ptr->sites = new_site_ptr;
  1700.     if (new_site_ptr != NULL)  new_unit_ptr->flags |= UFLAG_SITES;
  1701.   }
  1702.  
  1703.   return( KernelErrorCode );
  1704. }
  1705.  
  1706. /*****************************************************************************
  1707.   FUNCTION : kr_removeUnit
  1708.  
  1709.   PURPOSE  : Remove unit and all links from network
  1710.   NOTES    : 
  1711.  
  1712.   RETURNS  : Returns the error code 
  1713.   UPDATE   : 
  1714. ******************************************************************************/
  1715. krui_err  kr_removeUnit(struct Unit *unit_ptr)
  1716. {
  1717.  
  1718.   /*  delete inputs   */
  1719.   kr_deleteAllInputs( unit_ptr );
  1720.   /*  delete output links */
  1721.   kr_deleteAllOutputLinks( unit_ptr );
  1722.   /*  check references to the unit symbol   */
  1723.   krm_NTableReleaseSymbol( unit_ptr->unit_name, UNIT_SYM );
  1724.   /*  count units  */
  1725.   kr_countUnits( unit_ptr, UNIT_DELETE );
  1726.   /*  delete Unit */
  1727.   krm_releaseUnit( unit_ptr - unit_array );
  1728.  
  1729.   return( KernelErrorCode );
  1730. }
  1731.  
  1732.  
  1733. /*****************************************************************************
  1734.   FUNCTION : kr_copyUnit
  1735.  
  1736.   PURPOSE  : Copy a given unit, according to the copy mode
  1737.              1. copy unit (with it sites, if available) and input/output links
  1738.              2. copy unit (with it sites, if available) and input links
  1739.              3. copy unit (with it sites, if available) and output links
  1740.              4. copy unit (with it sites, if available) but no links
  1741.          Function has no effect on the current unit.
  1742.   NOTES    : Copying of output links is slow.
  1743.              If return code < 0, an error occured.
  1744.  
  1745.   RETURNS  : Returns the unit number of the new unit or error message < 0 , 
  1746.              if errors occured.
  1747.   UPDATE   : 
  1748. ******************************************************************************/
  1749. krui_err  kr_copyUnit(int copy_mode, int source_unit)
  1750. {
  1751.   struct Unit    *source_unit_ptr,
  1752.         *new_unit_ptr;
  1753.   int  new_unit_no;
  1754.  
  1755.  
  1756.   KernelErrorCode = KRERR_NO_ERROR;
  1757.  
  1758.   if ((source_unit_ptr = kr_getUnitPtr( source_unit )) == NULL)
  1759.     return( KernelErrorCode );
  1760.   if ((new_unit_no = krm_getUnit()) == 0)
  1761.     return( KernelErrorCode );
  1762.  
  1763.   new_unit_ptr = unit_array + new_unit_no;
  1764.  
  1765.   /*  copy unit (with it sites, if available) but no input/output links  */
  1766.   if (kr_copyUnitFrame( source_unit_ptr, new_unit_ptr ) != KRERR_NO_ERROR)
  1767.     return( KernelErrorCode );
  1768.  
  1769.   switch (copy_mode)
  1770.     {
  1771.     case ONLY_UNIT:
  1772.       break;
  1773.  
  1774.     case ONLY_INPUTS:
  1775.     /*    copy unit (with it sites, if available) and input links */
  1776.       (void) kr_copyInputLinks( source_unit_ptr, new_unit_ptr );
  1777.       break;
  1778.  
  1779.     case ONLY_OUTPUTS:
  1780.     /*  copy unit (with it sites, if available) and output links    */
  1781.       (void) kr_copyOutputLinks( source_unit_ptr, new_unit_ptr);
  1782.       break;
  1783.  
  1784.     case INPUTS_AND_OUTPUTS:
  1785.     /*  copy unit (with it sites, if available) and input/output links  */
  1786.       if (kr_copyOutputLinks( source_unit_ptr, new_unit_ptr) != KRERR_NO_ERROR)
  1787.     break;
  1788.  
  1789.       (void) kr_copyInputLinks( source_unit_ptr, new_unit_ptr );
  1790.       break;
  1791.  
  1792.     default:
  1793.       KernelErrorCode = KRERR_COPYMODE;
  1794.   }
  1795.  
  1796.   if (KernelErrorCode != KRERR_NO_ERROR)
  1797.     {
  1798.     kr_removeUnit( new_unit_ptr );  /*    delete Unit  */
  1799.     return( KernelErrorCode );
  1800.   }
  1801.   else
  1802.     {  /*  Successful copy   */
  1803.     new_unit_ptr->flags = source_unit_ptr->flags;  /*  copy flags  */
  1804.     /*  count units  */
  1805.     kr_countUnits( new_unit_ptr, UNIT_ADD );
  1806.     NetModified = TRUE;
  1807.     return( new_unit_no );
  1808.   }
  1809. }
  1810.  
  1811. /*#################################################
  1812.  
  1813. GROUP: Ftype Unit Functions
  1814.  
  1815. #################################################*/
  1816. /*****************************************************************************
  1817.   FUNCTION : kr_changeFtypeUnits
  1818.  
  1819.   PURPOSE  : changes all units in the network with the given functionality type
  1820.              to the new functions of the (new) functionality type
  1821.   NOTES    : 
  1822.  
  1823.   RETURNS  : 
  1824.   UPDATE   : 
  1825. ******************************************************************************/
  1826. void   kr_changeFtypeUnits(struct FtypeUnitStruct *Ftype_entry)
  1827. {
  1828.   register struct Unit   *unit_ptr;
  1829.  
  1830.  
  1831.   if (NoOfUnits == 0)  return;  /*  no units  */
  1832.  
  1833.   FOR_ALL_UNITS( unit_ptr )
  1834.     if UNIT_IN_USE( unit_ptr )
  1835.       {     /*  unit is in use  */
  1836.       if (unit_ptr->Ftype_entry == Ftype_entry)
  1837.     {  /*  unit with this type was found. Now change the transfer functions
  1838.            of the unit to the modified functionality type */
  1839.         unit_ptr->act_func = Ftype_entry->act_func;
  1840.         unit_ptr->out_func = Ftype_entry->out_func;
  1841.         unit_ptr->act_deriv_func = Ftype_entry->act_deriv_func;
  1842.         }
  1843.       }
  1844.  
  1845.   NetModified = TRUE;
  1846. }
  1847.  
  1848. /*****************************************************************************
  1849.   FUNCTION : kr_deleteUnitsFtype
  1850.  
  1851.   PURPOSE  : delete the functionality type of the units with the given type
  1852.   NOTES    : 
  1853.  
  1854.   RETURNS  : 
  1855.   UPDATE   : 
  1856. ******************************************************************************/
  1857. void  kr_deleteUnitsFtype(struct FtypeUnitStruct *ftype_ptr)
  1858. {
  1859.   register struct Unit   *unit_ptr;
  1860.  
  1861.  
  1862.   if (NoOfUnits == 0)  return;  /*  no units  */
  1863.  
  1864.   FOR_ALL_UNITS( unit_ptr )
  1865.     if UNIT_IN_USE( unit_ptr )
  1866.       /*  unit is in use  */
  1867.       if (unit_ptr->Ftype_entry == ftype_ptr)
  1868.         unit_ptr->Ftype_entry = NULL;
  1869. }
  1870.  
  1871. /*****************************************************************************
  1872.   FUNCTION : kr_makeFtypeUnit
  1873.  
  1874.   PURPOSE  : create a new unit with the given functionality type
  1875.   NOTES    : 
  1876.  
  1877.   RETURNS  : 
  1878.   UPDATE   : 
  1879. ******************************************************************************/
  1880. int  kr_makeFtypeUnit(char *Ftype_symbol)
  1881. {
  1882.   register struct Site    *ftype_site, *site_ptr;
  1883.   struct Unit  *unit_ptr;
  1884.   struct FtypeUnitStruct  *ftype_ptr;
  1885.   int  unit_no;
  1886.  
  1887.  
  1888.   KernelErrorCode = KRERR_NO_ERROR;
  1889.  
  1890.   if (!kr_symbolCheck( Ftype_symbol ))
  1891.     return( KernelErrorCode );
  1892.  
  1893.   if ((ftype_ptr = krm_FtypeSymbolSearch( Ftype_symbol ) ) == NULL)
  1894.     {  /*  Ftype name isn't defined    */
  1895.     KernelErrorCode = KRERR_FTYPE_SYMBOL;
  1896.     return( KernelErrorCode );
  1897.   }
  1898.  
  1899.   unit_no = kr_makeDefaultUnit();
  1900.   if (KernelErrorCode != KRERR_NO_ERROR)
  1901.     return( KernelErrorCode );
  1902.  
  1903.   unit_ptr = unit_array + unit_no;
  1904.  
  1905.   unit_ptr->Ftype_entry = ftype_ptr;
  1906.   unit_ptr->out_func    = ftype_ptr->out_func;
  1907.   unit_ptr->act_func    = ftype_ptr->act_func;
  1908.   unit_ptr->act_deriv_func = ftype_ptr->act_deriv_func;
  1909.  
  1910.   ftype_site = ftype_ptr->sites;
  1911.  
  1912.   /*  make sites  */
  1913.   while (ftype_site != NULL)
  1914.     {   /*  Ftype has sites */
  1915.     if ((site_ptr = krm_getSite()) == NULL)
  1916.       {  /*  memory alloc failed */
  1917.       krm_releaseAllSites( unit_ptr->sites );
  1918.       unit_ptr->sites = NULL;
  1919.       KernelErrorCode = KRERR_INSUFFICIENT_MEM;
  1920.       return( KernelErrorCode );
  1921.     }
  1922.  
  1923.     site_ptr->next = unit_ptr->sites;
  1924.     unit_ptr->sites = site_ptr;
  1925.  
  1926.     site_ptr->site_table = ftype_site->site_table;
  1927.     ftype_site = ftype_site->next;
  1928.   }
  1929.  
  1930.   if (ftype_ptr->sites != NULL)
  1931.     unit_ptr->flags |= UFLAG_SITES;     /*  unit has now sites  */
  1932.  
  1933.   return( unit_no );
  1934. }
  1935.  
  1936. /*****************************************************************************
  1937.   FUNCTION : kr_FtypeSiteSearch
  1938.  
  1939.   PURPOSE  : 
  1940.   NOTES    : 
  1941.  
  1942.   RETURNS  : returns TRUE, if there exists the given site at the given ftype 
  1943.              entry
  1944.   UPDATE   : 
  1945. ******************************************************************************/
  1946. bool  kr_FtypeSiteSearch(struct Site *ftype_first_site, 
  1947.              struct SiteTable *site_table_ptr)
  1948. {
  1949.   register struct  Site      *site_ptr;
  1950.  
  1951.  
  1952.   for (site_ptr = ftype_first_site; site_ptr != NULL; site_ptr = site_ptr->next)
  1953.     if (site_ptr->site_table == site_table_ptr)
  1954.       return( TRUE );
  1955.  
  1956.   return( FALSE );
  1957. }
  1958.  
  1959. /*****************************************************************************
  1960.   FUNCTION : kr_changeFtypeUnit
  1961.  
  1962.   PURPOSE  : change the properties of the given unit to the properties of the
  1963.              given F-Type 
  1964.   NOTES    : 
  1965.  
  1966.   RETURNS  : 
  1967.   UPDATE   : 
  1968. ******************************************************************************/
  1969. void    kr_changeFtypeUnit(struct Unit *unit_ptr, 
  1970.                struct FtypeUnitStruct *ftype_ptr)
  1971. {
  1972.   FlagWord    flags;
  1973.   struct  Site  *site_ptr,
  1974.                 *pred_site_ptr,
  1975.                 *tmp_ptr,
  1976.                 *ftype_site;
  1977.  
  1978.  
  1979.   unit_ptr->out_func = ftype_ptr->out_func;
  1980.   unit_ptr->act_func = ftype_ptr->act_func;
  1981.   unit_ptr->act_deriv_func = ftype_ptr->act_deriv_func;
  1982.  
  1983.   flags = unit_ptr->flags & UFLAG_INPUT_PAT;
  1984.  
  1985.   switch (flags)
  1986.     {
  1987.     case  UFLAG_NO_INP:
  1988.       /*  Unit has no inputs  */
  1989.       if (ftype_ptr->sites != NULL)
  1990.         /*    Ftype has sites, delete unit's Ftype  */
  1991.         unit_ptr->Ftype_entry = NULL;
  1992.       else
  1993.         /*    Ftype and unit don't have sites */
  1994.         unit_ptr->Ftype_entry = ftype_ptr;    /* unit accept Ftype and inputs */
  1995.  
  1996.       return;     /*  done !  */
  1997.  
  1998.     case  UFLAG_SITES:
  1999.       /*  Unit has sites  */
  2000.       ftype_site = ftype_ptr->sites;
  2001.       if (ftype_site == NULL)
  2002.         {  /* unit has sites, but Ftype hasn't sites, 
  2003.           delete unit's Ftype and all inputs  */
  2004.         unit_ptr->Ftype_entry = NULL;
  2005.  
  2006.         kr_deleteAllInputs( unit_ptr );
  2007.         unit_ptr->flags = UFLAG_INITIALIZED;  /*  unit has no inputs now !    */
  2008.         }
  2009.       else
  2010.         {     /*  both unit and Ftype have sites: check sites  */
  2011.         unit_ptr->Ftype_entry = ftype_ptr;
  2012.  
  2013.         site_ptr = unit_ptr->sites;
  2014.         pred_site_ptr = NULL;
  2015.  
  2016.         do
  2017.           {
  2018.           if ( ! kr_FtypeSiteSearch( ftype_site, site_ptr->site_table ))
  2019.             {  /*  Ftype and unit site definitions are not equivalent: 
  2020.            remove site    */
  2021.             if (pred_site_ptr == NULL)
  2022.               {   /*  this is the first site at the unit  */
  2023.               unit_ptr->sites = site_ptr->next;
  2024.  
  2025.               if (site_ptr->next == NULL)
  2026.                 /*  unit don't has any inputs   */
  2027.                 unit_ptr->flags &= (~UFLAG_INPUT_PAT);
  2028.               }
  2029.             else
  2030.               {   /*  this site isn't the first site at the unit  */
  2031.               pred_site_ptr->next = site_ptr->next;
  2032.               pred_site_ptr = site_ptr;
  2033.               }
  2034.  
  2035.         /*  work with temporary pointer and get */
  2036.             tmp_ptr = site_ptr;
  2037.  
  2038.         /*  next site pointer BEFORE krm_releaseSite    */
  2039.             site_ptr = site_ptr->next;
  2040.  
  2041.         /*  (important in a multiprocessor system   */
  2042.             krm_releaseAllLinks( tmp_ptr->links );    
  2043.             krm_releaseSite( tmp_ptr );
  2044.             /*    delete unit's Ftype */
  2045.             unit_ptr->Ftype_entry = NULL;
  2046.             }
  2047.           else
  2048.             {
  2049.             pred_site_ptr = site_ptr;
  2050.             site_ptr = site_ptr->next;
  2051.             }
  2052.           }
  2053.         while (site_ptr != NULL);
  2054.  
  2055.         if (unit_ptr->sites == NULL)
  2056.           unit_ptr->flags = UFLAG_INITIALIZED;  /*  unit has no inputs now !  */
  2057.         }
  2058.  
  2059.       return;
  2060.  
  2061.  
  2062.     case  UFLAG_DLINKS:
  2063.     /*  Unit has direct links   */
  2064.       if (ftype_ptr->sites != NULL)
  2065.         { /*  unit has direct links, but Ftype entry has sites: delete links  */
  2066.         unit_ptr->Ftype_entry = NULL;
  2067.  
  2068.         kr_deleteAllInputs( unit_ptr );
  2069.         unit_ptr->flags = UFLAG_INITIALIZED;  /*  unit has no inputs now !    */
  2070.         }
  2071.       else
  2072.         { /* unit has direct links and Ftype has no sites: use direct links  */
  2073.         unit_ptr->Ftype_entry = ftype_ptr;
  2074.         }
  2075.  
  2076.     }
  2077. }
  2078.  
  2079. /*****************************************************************************
  2080.   FUNCTION : kr_changeFtypeSites
  2081.  
  2082.   PURPOSE  : change a site at the F-Type
  2083.   NOTES    : 
  2084.  
  2085.   RETURNS  : 
  2086.   UPDATE   : 
  2087. ******************************************************************************/
  2088. void    kr_changeFtypeSites(struct FtypeUnitStruct *Ftype_entry, 
  2089.                 struct SiteTable *old_site_table, 
  2090.                 struct SiteTable *new_site_table)
  2091. {
  2092.   struct Unit   *unit_ptr;
  2093.   struct Site   *site_ptr;
  2094.  
  2095.  
  2096.   if (NoOfUnits == 0)  return;  /*  no units  */
  2097.  
  2098.   FOR_ALL_UNITS( unit_ptr )
  2099.     if UNIT_IN_USE( unit_ptr )
  2100.       {     /*  unit is in use  */
  2101.       if (unit_ptr->Ftype_entry == Ftype_entry)
  2102.         {
  2103.     FOR_ALL_SITES( unit_ptr, site_ptr )
  2104.           if (site_ptr->site_table == old_site_table)
  2105.             site_ptr->site_table = new_site_table;
  2106.       }
  2107.     }
  2108.  
  2109.   NetModified = TRUE;
  2110. }
  2111.  
  2112.  
  2113. /*#################################################
  2114.  
  2115. GROUP: Miscellanous
  2116.  
  2117. #################################################*/
  2118. /*****************************************************************************
  2119.   FUNCTION : kr_flags2TType
  2120.  
  2121.   PURPOSE  : translate unit flags to the topological type of the unit
  2122.   NOTES    : 
  2123.  
  2124.   RETURNS  : 
  2125.   UPDATE   : 
  2126. ******************************************************************************/
  2127. int  kr_flags2TType(int flags)
  2128. {
  2129.   KernelErrorCode = KRERR_NO_ERROR;
  2130.  
  2131.   switch (flags)
  2132.     {
  2133.     case UFLAG_TTYP_UNKN:  return( UNKNOWN );
  2134.     case UFLAG_TTYP_IN  :  return( INPUT );
  2135.     case UFLAG_TTYP_OUT :  return( OUTPUT );
  2136.     case UFLAG_TTYP_DUAL:  return( DUAL );
  2137.     case UFLAG_TTYP_HIDD:  return( HIDDEN );
  2138.     case UFLAG_TTYP_SPEC:  return( SPECIAL );
  2139.     case UFLAG_TTYP_SPEC_I: return (SPECIAL_I) ;
  2140.     case UFLAG_TTYP_SPEC_O: return (SPECIAL_O) ;
  2141.     case UFLAG_TTYP_SPEC_H: return (SPECIAL_H) ;
  2142.     case UFLAG_TTYP_SPEC_D: return (SPECIAL_D) ;
  2143.       /* case UFLAG_TTYP_SPEC_X and 
  2144.      case UFLAG_TTYP_N_SPEC_X are no true TType*/
  2145.     
  2146.     default: KernelErrorCode = KRERR_TTYPE;
  2147.          return( UNKNOWN );
  2148.   }
  2149. }
  2150.  
  2151. /*****************************************************************************
  2152.   FUNCTION : kr_TType2Flags
  2153.  
  2154.   PURPOSE  : translate the topological type to unit flags
  2155.   NOTES    : 
  2156.  
  2157.   RETURNS  : 
  2158.   UPDATE   : 
  2159. ******************************************************************************/
  2160. int  kr_TType2Flags(int ttype)
  2161. {
  2162.   KernelErrorCode = KRERR_NO_ERROR;
  2163.  
  2164.   switch (ttype)
  2165.     {
  2166.     case UNKNOWN:  return( UFLAG_TTYP_UNKN );
  2167.     case INPUT    :  return( UFLAG_TTYP_IN );
  2168.     case OUTPUT :  return( UFLAG_TTYP_OUT );
  2169.     case DUAL    :  return( UFLAG_TTYP_DUAL );
  2170.     case HIDDEN :  return( UFLAG_TTYP_HIDD );
  2171.     case SPECIAL:  return( UFLAG_TTYP_SPEC );
  2172.     case SPECIAL_I: return (UFLAG_TTYP_SPEC_I) ;
  2173.     case SPECIAL_O: return (UFLAG_TTYP_SPEC_O) ;
  2174.     case SPECIAL_H: return (UFLAG_TTYP_SPEC_H) ;
  2175.     case SPECIAL_D: return (UFLAG_TTYP_SPEC_D) ;
  2176.     case SPECIAL_X: return (UFLAG_TTYP_SPEC_X) ;
  2177.     case N_SPECIAL_X: return (UFLAG_TTYP_N_SPEC_X) ;
  2178.     default:  KernelErrorCode = KRERR_TTYPE;
  2179.           /*  return( KernelErrorCode );  */
  2180.           return( -1 );
  2181.   }
  2182. }
  2183. /*****************************************************************************
  2184.   FUNCTION : kr_updateUnitOutputs
  2185.  
  2186.   PURPOSE  : update the outputs of all units in the network
  2187.   NOTES    : 
  2188.  
  2189.   RETURNS  : 
  2190.   UPDATE   : 
  2191. ******************************************************************************/
  2192. void    kr_updateUnitOutputs(void)
  2193. {
  2194.   register struct Unit   *unit_ptr;
  2195.  
  2196.  
  2197.   FOR_ALL_UNITS( unit_ptr )
  2198.     if ( (unit_ptr->flags & UFLAG_INITIALIZED) == UFLAG_INITIALIZED)
  2199.       {     /*  unit is in use and enabled  */
  2200.       if (unit_ptr->out_func == NULL)
  2201.         /*  Identity Function   */
  2202.         unit_ptr->Out.output = unit_ptr->act;
  2203.       else
  2204.         unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
  2205.       }
  2206. }
  2207.  
  2208.  
  2209. /*****************************************************************************
  2210.   FUNCTION : kr_getNoOfUnits
  2211.  
  2212.   PURPOSE  : returns the no. of units of the specified topologic type
  2213.              (i.e. Input, Hidden, Output or Special units)
  2214.   NOTES    : 
  2215.  
  2216.   RETURNS  : 
  2217.   UPDATE   : 
  2218. ******************************************************************************/
  2219. int  kr_getNoOfUnits(int UnitTType)
  2220. {
  2221.   register struct Unit   *unit_ptr;
  2222.   register int   no_of_units;
  2223.   register FlagWord      ttyp_flg;
  2224.   int   flg;
  2225.  
  2226.  
  2227.   if ((NoOfUnits == 0) || ((flg = kr_TType2Flags( UnitTType )) == -1))
  2228.     return( 0 );  /*  no units or this topologic type doesn't exist  */
  2229.  
  2230.   ttyp_flg = (FlagWord) flg;
  2231.   no_of_units = 0;
  2232.   FOR_ALL_UNITS( unit_ptr )
  2233.     if ( ((unit_ptr->flags & UFLAG_TTYP_PAT) == ttyp_flg) &&
  2234.          UNIT_IN_USE( unit_ptr ) )
  2235.       no_of_units++;
  2236.  
  2237.   return( no_of_units );
  2238. }
  2239.  
  2240.  
  2241. /*****************************************************************************
  2242.   FUNCTION : kr_forceUnitGC
  2243.  
  2244.   PURPOSE  : force unit array garbage collection
  2245.   NOTES    : 
  2246.  
  2247.   RETURNS  : 
  2248.   UPDATE   : 
  2249. ******************************************************************************/
  2250. void  kr_forceUnitGC(void)
  2251. {
  2252.   krm_unitArrayGC();
  2253. }
  2254.  
  2255.  
  2256. /*#################################################
  2257.  
  2258. GROUP: Functions default presettings
  2259.  
  2260. #################################################*/
  2261.  
  2262. /*****************************************************************************
  2263.   FUNCTION : kr_getUnitDefaults
  2264.  
  2265.   PURPOSE  : 
  2266.   NOTES    : 
  2267.  
  2268.   RETURNS  : Returns information about the unit default settings. 
  2269.   UPDATE   : 
  2270. ******************************************************************************/
  2271. void    kr_getUnitDefaults(FlintType *act, FlintType *bias, int *ttflags, 
  2272.                int *subnet_no, int *layer_no, char **act_func, 
  2273.                char **out_func)
  2274. {
  2275.   static char  activation_func[FUNCTION_NAME_MAX_LEN],
  2276.                output_func[FUNCTION_NAME_MAX_LEN];
  2277.  
  2278.  
  2279.   *act          = DefaultIAct;
  2280.   *bias         = DefaultBias;
  2281.   *ttflags    = (int) DefaultSType;
  2282.   *subnet_no    = DefaultSubnetNo;
  2283.   *layer_no     = DefaultLayerNo;
  2284.  
  2285.   strcpy( activation_func, krf_getCurrentNetworkFunc( ACT_FUNC ) );
  2286.   *act_func = activation_func;
  2287.   strcpy( output_func, krf_getCurrentNetworkFunc( OUT_FUNC ) );
  2288.   *out_func = output_func;
  2289. }
  2290.  
  2291. /*****************************************************************************
  2292.   FUNCTION : kr_setUnitDefaults
  2293.  
  2294.   PURPOSE  : Changes the unit default settings.
  2295.   NOTES    : 
  2296.  
  2297.   RETURNS  : Returns error code
  2298.   UPDATE   : 
  2299. ******************************************************************************/
  2300. krui_err  kr_setUnitDefaults(FlintTypeParam act, FlintTypeParam bias, 
  2301.                  int ttflags, int subnet_no, int layer_no, 
  2302.                  char *act_func, char *out_func)
  2303. {
  2304.   FunctionPtr  act_func_ptr,
  2305.                act_deriv_func_ptr,
  2306.                out_func_ptr;
  2307.  
  2308.  
  2309.   KernelErrorCode = KRERR_NO_ERROR;
  2310.  
  2311.  
  2312.   if (!krf_funcSearch( act_func, ACT_FUNC, &act_func_ptr))
  2313.     return( KernelErrorCode );
  2314.   if (!krf_funcSearch( act_func, ACT_DERIV_FUNC, &act_deriv_func_ptr))
  2315.     return( KernelErrorCode );
  2316.   if (!krf_funcSearch( out_func, OUT_FUNC, &out_func_ptr))
  2317.     return( KernelErrorCode );
  2318.  
  2319.   if (krf_setCurrentNetworkFunc( act_func, ACT_FUNC ) != KRERR_NO_ERROR)
  2320.     return( KernelErrorCode );
  2321.   if (krf_setCurrentNetworkFunc( out_func, OUT_FUNC ) != KRERR_NO_ERROR)
  2322.     return( KernelErrorCode );
  2323.  
  2324.   DefaultIAct       = (FlintType) act;
  2325.   DefaultBias       = (FlintType) bias;
  2326.   DefaultSType        = (FlagWord) ttflags;
  2327.   DefaultPosX       = DEF_POS_X;
  2328.   DefaultPosY       = DEF_POS_Y;
  2329.  
  2330. #ifdef KERNEL3D
  2331.   DefaultPosZ       = DEF_POS_Z;
  2332. #endif
  2333.  
  2334.   DefaultSubnetNo   = subnet_no;
  2335.   DefaultLayerNo    = layer_no;
  2336.  
  2337.   DefaultUFuncOut   = (OutFuncPtr) out_func_ptr;
  2338.   DefaultUFuncAct   = (ActFuncPtr) act_func_ptr;
  2339.   DefaultUFuncActDeriv = (ActDerivFuncPtr) act_deriv_func_ptr;
  2340.  
  2341.   return( KernelErrorCode );
  2342. }
  2343.  
  2344.  
  2345. /*#################################################
  2346.  
  2347. GROUP: Topological Sorting Functions
  2348.  
  2349. #################################################*/
  2350.  
  2351. /*****************************************************************************
  2352.   FUNCTION : clr_T_flags
  2353.  
  2354.   PURPOSE  : Clears the 'touch' (refresh) flag of all units
  2355.   NOTES    : 
  2356.  
  2357.   RETURNS  : 
  2358.   UPDATE   : 
  2359. ******************************************************************************/
  2360. static void  clr_T_flags(void)
  2361. {
  2362.   register struct Unit   *unit_ptr;
  2363.  
  2364.  
  2365.   FOR_ALL_UNITS( unit_ptr )
  2366.     if (UNIT_IN_USE( unit_ptr ))
  2367.       {
  2368.       unit_ptr->flags &= ~UFLAG_REFRESH;
  2369.       unit_ptr->lln = 0;
  2370.     }
  2371. }
  2372.  
  2373. /*****************************************************************************
  2374.   FUNCTION : DepthFirst1
  2375.  
  2376.   PURPOSE  : Depth search routine for topological sorting
  2377.   NOTES    : 
  2378.  
  2379.   RETURNS  : 
  2380.   UPDATE   : 
  2381. ******************************************************************************/
  2382. static void  DepthFirst1(struct Unit *unit_ptr, int depth)
  2383. {
  2384.   struct Site   *site_ptr;
  2385.   struct Link   *link_ptr;
  2386.  
  2387.  
  2388.   if (unit_ptr->flags & UFLAG_REFRESH)
  2389.     {  /*  the 'touch' flag is set: don't continue search  */
  2390.     if (unit_ptr->lln == 0)
  2391.       {  /*  logical layer no. isn't set => Cycle found  */
  2392.       topo_msg.no_of_cycles++;
  2393.       if (topo_msg.error_code == KRERR_NO_ERROR)
  2394.     {  /*  remember the cycle unit    */
  2395.         topo_msg.src_error_unit = unit_ptr - unit_array;
  2396.         topo_msg.error_code = KRERR_CYCLES;
  2397.       }
  2398.     }
  2399.  
  2400.     return;
  2401.   }
  2402.   else
  2403.     /*    set the 'touch' flag  */
  2404.     unit_ptr->flags |= UFLAG_REFRESH;
  2405.  
  2406.   switch (unit_ptr->flags & UFLAG_INPUT_PAT)
  2407.     {
  2408.     case  UFLAG_DLINKS:   /*  unit has direct links  */
  2409.       FOR_ALL_LINKS( unit_ptr, link_ptr )
  2410.     DepthFirst1( link_ptr->to, depth + 1 );  /*  increase depth  */
  2411.  
  2412.       break;
  2413.  
  2414.     case  UFLAG_SITES:    /*  unit has sites  */
  2415.     FOR_ALL_SITES_AND_LINKS( unit_ptr, site_ptr, link_ptr )
  2416.       DepthFirst1( link_ptr->to, depth + 1 );  /*  increase depth  */
  2417.  
  2418.       break;
  2419.   }
  2420.  
  2421.   /*  remember the depth (for cycle detection and statistics)  */
  2422.   unit_ptr->lln = depth;  
  2423.   *global_topo_ptr++ = unit_ptr;  /*  store sorted unit pointer  */
  2424. }
  2425.  
  2426. /*****************************************************************************
  2427.   FUNCTION : DepthFirst2
  2428.  
  2429.   PURPOSE  : Depth search routine for topology check function
  2430.   NOTES    : 
  2431.  
  2432.   RETURNS  : 
  2433.   UPDATE   : 
  2434. ******************************************************************************/
  2435. static void  DepthFirst2(struct Unit *unit_ptr, int depth)
  2436. {
  2437.   struct Site   *site_ptr;
  2438.   struct Link   *link_ptr;
  2439.  
  2440.  
  2441.   if (unit_ptr->flags & UFLAG_REFRESH)
  2442.     {  /*  the 'touch' flag is set: don't continue search  */
  2443.     if (unit_ptr->lln == 0)
  2444.       {  /*  logical layer no. isn't set => Cycle found  */
  2445.       topo_msg.no_of_cycles++;
  2446.       if (topo_msg.error_code == KRERR_NO_ERROR)
  2447.     {  /*  remember the cycle unit    */
  2448.         topo_msg.src_error_unit = unit_ptr - unit_array;
  2449.         topo_msg.error_code = KRERR_CYCLES;
  2450.       }
  2451.     }
  2452.  
  2453.     return;
  2454.   }
  2455.   else
  2456.     /*    set the 'touch' flag  */
  2457.     unit_ptr->flags |= UFLAG_REFRESH;
  2458.  
  2459.   switch (unit_ptr->flags & UFLAG_INPUT_PAT)
  2460.     {
  2461.     case  UFLAG_DLINKS:   /*  unit has direct links  */
  2462.       FOR_ALL_LINKS( unit_ptr, link_ptr )
  2463.     DepthFirst2( link_ptr->to, depth + 1 );  /*  increase depth  */
  2464.  
  2465.       break;
  2466.  
  2467.     case  UFLAG_SITES:    /*  unit has sites  */
  2468.       FOR_ALL_SITES_AND_LINKS( unit_ptr, site_ptr, link_ptr )
  2469.     DepthFirst2( link_ptr->to, depth + 1 );  /*  increase depth  */
  2470.  
  2471.       break;
  2472.   }
  2473.  
  2474.   /*  remember the depth (for cycle detection and statistics)  */
  2475.   unit_ptr->lln = depth;
  2476.  
  2477.   /*  store highest layer no.  */
  2478.   if (depth > topo_msg.no_of_layers)  topo_msg.no_of_layers = depth;
  2479. }
  2480.  
  2481. /*****************************************************************************
  2482.   FUNCTION : DepthFirst3
  2483.  
  2484.   PURPOSE  : Depth search routine for topological sorting in feedforward networks
  2485.   NOTES    : 
  2486.  
  2487.   RETURNS  : 
  2488.   UPDATE   : 
  2489. ******************************************************************************/
  2490. static void  DepthFirst3(struct Unit *unit_ptr, int depth)
  2491. {
  2492.   struct Site   *site_ptr;
  2493.   struct Link   *link_ptr;
  2494.  
  2495.  
  2496.   if (unit_ptr->flags & UFLAG_REFRESH)
  2497.     {  /*  the 'touch' flag is set: don't continue search  */
  2498.     topo_msg.src_error_unit = unit_ptr - unit_array; /*  store unit number  */
  2499.  
  2500.     if IS_OUTPUT_UNIT( unit_ptr )
  2501.       {  /*  this output unit has a output connection to another unit  */
  2502.       if (topo_msg.error_code == KRERR_NO_ERROR)
  2503.         topo_msg.error_code = KRERR_O_UNITS_CONNECT;
  2504.     }
  2505.     else
  2506.       if (unit_ptr->lln == 0)
  2507.         {  /*  logical layer no. isn't set => Cycle found  */
  2508.         topo_msg.no_of_cycles++;
  2509.         if (topo_msg.error_code == KRERR_NO_ERROR)
  2510.           topo_msg.error_code = KRERR_CYCLES;
  2511.       }
  2512.  
  2513.     return;
  2514.   }
  2515.   else
  2516.     /*    set the 'touch' flag  */
  2517.     unit_ptr->flags |= UFLAG_REFRESH;
  2518.  
  2519.   switch (unit_ptr->flags & UFLAG_INPUT_PAT)
  2520.     {
  2521.     case  UFLAG_DLINKS:   /*  unit has direct links  */
  2522.       FOR_ALL_LINKS( unit_ptr, link_ptr )
  2523.     DepthFirst3( link_ptr->to, depth + 1 );  /*  increase depth  */
  2524.  
  2525.       break;
  2526.  
  2527.     case  UFLAG_SITES:    /*  unit has sites  */
  2528.       FOR_ALL_SITES_AND_LINKS( unit_ptr, site_ptr, link_ptr )
  2529.     DepthFirst3( link_ptr->to, depth + 1 );  /*  increase depth  */
  2530.  
  2531.       break;
  2532.   }
  2533.  
  2534.   /*  remember the depth (for cycle detection and statistics)  */
  2535.   unit_ptr->lln = depth;
  2536.  
  2537.   /*  store only hidden units  */
  2538.   if IS_HIDDEN_UNIT( unit_ptr )
  2539.     *global_topo_ptr++ = unit_ptr;  /*    store sorted unit pointer  */
  2540. }
  2541.  
  2542.  
  2543. /*****************************************************************************
  2544.   FUNCTION : kr_topoSortT
  2545.  
  2546.   PURPOSE  : Sort units topological (general version) and stores the
  2547.              pointers to this units in the topologic array
  2548.   NOTES    : Units are not sorted by their topologic type (that's not possible 
  2549.              in the general case)
  2550.  
  2551.   RETURNS  : error code
  2552.   UPDATE   : 
  2553. ******************************************************************************/
  2554. static krui_err  kr_topoSortT(void)
  2555. {
  2556.   register struct Unit     *unit_ptr;
  2557.   int    io_units;
  2558.  
  2559.  
  2560.   KernelErrorCode = KRERR_NO_ERROR;  /*  reset return code  */
  2561.   clr_T_flags();    /*    reset units 'touch' flags  */
  2562.   global_topo_ptr = topo_ptr_array;  /*  initialize global pointer */
  2563.  
  2564.   /*  limit left side of the topological array with NULL pointer  */
  2565.   *global_topo_ptr++ = NULL;
  2566.  
  2567.   /*  put all input units in the topologic array  */
  2568.   io_units = 0;
  2569.   FOR_ALL_UNITS( unit_ptr )
  2570.     if (IS_INPUT_UNIT( unit_ptr ) && UNIT_IN_USE( unit_ptr ))
  2571.       io_units++;    /*  there is a input unit  */
  2572.  
  2573.   if ((NoOfInputUnits = io_units) == 0)
  2574.     {  /*  no input units */
  2575.     KernelErrorCode = KRERR_NO_INPUT_UNITS;
  2576.     return( KernelErrorCode );
  2577.   }
  2578.  
  2579.   /*  begin depth search at the first output unit  */
  2580.   io_units = 0;
  2581.   FOR_ALL_UNITS( unit_ptr )
  2582.     if ( IS_OUTPUT_UNIT( unit_ptr ) && UNIT_IN_USE( unit_ptr ) )
  2583.       {
  2584.       io_units++;  /*  there is a output unit  */
  2585.  
  2586.       /*  sort the units topological (using depth search algorithm, 
  2587.       starting at this output unit */
  2588.       DepthFirst1( unit_ptr, 1 );  
  2589.       if (topo_msg.error_code != KRERR_NO_ERROR)
  2590.         {  /*  stop if an error occured  */
  2591.         KernelErrorCode = topo_msg.error_code;
  2592.         return( KernelErrorCode );
  2593.       }
  2594.     }
  2595.  
  2596.   if ((NoOfOutputUnits = io_units) == 0)
  2597.     {  /*  no output units */
  2598.     KernelErrorCode = KRERR_NO_OUTPUT_UNITS;
  2599.     return( KernelErrorCode );
  2600.   }
  2601.  
  2602.   /*  limit right side of the topologic array with NULL pointer  */
  2603.   *global_topo_ptr++ = NULL;
  2604.  
  2605.   /*  calc. no. of sorted units  */
  2606.   no_of_topo_units = (global_topo_ptr - topo_ptr_array) - 2;
  2607.  
  2608.   /*  search for dead units i.e. units without inputs  */
  2609.   FOR_ALL_UNITS( unit_ptr )
  2610.     if ( !(unit_ptr->flags & UFLAG_REFRESH) &&
  2611.          UNIT_IN_USE( unit_ptr ) )
  2612.       {
  2613.       topo_msg.no_of_dead_units++;
  2614.       if (topo_msg.src_error_unit == 0)
  2615.         topo_msg.src_error_unit = unit_ptr - unit_array; /* store the unit no.*/
  2616.     }
  2617.  
  2618.   if (topo_msg.no_of_dead_units != 0)
  2619.     KernelErrorCode = KRERR_DEAD_UNITS;
  2620.  
  2621.   return( KernelErrorCode );
  2622. }
  2623.  
  2624.  
  2625. /*****************************************************************************
  2626.   FUNCTION : kr_topoSortT
  2627.  
  2628.   PURPOSE  : Sorts units topological in feed-forward networks and stores the
  2629.              pointers to these units in the topologic array in the following 
  2630.          order:
  2631.          - input,
  2632.          - hidden and
  2633.          - output units
  2634.  
  2635.              This function make following assumtions (like all learning 
  2636.          functions for feed-forward networks):
  2637.              a) input units doesn't have input connections to other units and
  2638.              b) output units doesn't have outputs connections to other units.
  2639.   NOTES    : 
  2640.  
  2641.   RETURNS  : error code
  2642.   UPDATE   : 
  2643. ******************************************************************************/
  2644. static krui_err  kr_topoSortFF(void)
  2645. {
  2646.   register struct Unit     *unit_ptr;
  2647.   int    io_units;
  2648.  
  2649.  
  2650.   KernelErrorCode = KRERR_NO_ERROR;  /*  reset return code  */
  2651.   clr_T_flags();    /*    reset units 'touch' flags  */
  2652.   global_topo_ptr = topo_ptr_array;  /*  initialize global pointer */
  2653.  
  2654.   /*  limit left side of the topological array with NULL pointer  */
  2655.   *global_topo_ptr++ = NULL;
  2656.  
  2657.   /*  put all input units in the topologic array  */
  2658.   io_units = 0;
  2659.   FOR_ALL_UNITS( unit_ptr )
  2660.     if (IS_INPUT_UNIT( unit_ptr ) && UNIT_IN_USE( unit_ptr ))
  2661.       {
  2662.       if UNIT_HAS_INPUTS( unit_ptr )
  2663.     {  /*  this input unit has a connection to another unit  */
  2664.  
  2665.     /*  store the unit no.  */
  2666.     topo_msg.dest_error_unit = unit_ptr - unit_array;  
  2667.  
  2668.     KernelErrorCode = KRERR_I_UNITS_CONNECT;  /*  input unit has input  */
  2669.         return( KernelErrorCode );
  2670.       }
  2671.  
  2672.       io_units++;    /*  there is a input unit  */
  2673.       *global_topo_ptr++ = unit_ptr;  /*  save input unit  */
  2674.     }
  2675.  
  2676.   if ((NoOfInputUnits = io_units) == 0)
  2677.     {  /*  no input units */
  2678.     KernelErrorCode = KRERR_NO_INPUT_UNITS;
  2679.     return( KernelErrorCode );
  2680.   }
  2681.  
  2682.   /*  limit input units in the topological array with NULL pointer  */
  2683.   *global_topo_ptr++ = NULL;
  2684.  
  2685.   /*  begin depth search at the first output unit  */
  2686.   io_units = 0;
  2687.   FOR_ALL_UNITS( unit_ptr )
  2688.     if (IS_OUTPUT_UNIT( unit_ptr ) && UNIT_IN_USE( unit_ptr ))
  2689.       {
  2690.       io_units++;    /*  there is a output unit  */
  2691.  
  2692.       /*  sort the units topological (using depth search algorithm, 
  2693.       starting at this output unit */
  2694.       DepthFirst3( unit_ptr, 1 );  
  2695.       if (topo_msg.error_code != KRERR_NO_ERROR)
  2696.         {  /*  stop if an error occured  */
  2697.         KernelErrorCode = topo_msg.error_code;
  2698.         return( KernelErrorCode );
  2699.       }
  2700.     }
  2701.  
  2702.   if ((NoOfOutputUnits = io_units) == 0)
  2703.     {  /*  no output units */
  2704.     KernelErrorCode = KRERR_NO_OUTPUT_UNITS;
  2705.     return( KernelErrorCode );
  2706.   }
  2707.  
  2708.   /*  limit hidden units in the topological array with NULL pointer  */
  2709.   *global_topo_ptr++ = NULL;
  2710.  
  2711.   /*  put all output units in the topological array  */
  2712.   FOR_ALL_UNITS( unit_ptr )
  2713.     if (IS_OUTPUT_UNIT(unit_ptr ) && UNIT_IN_USE( unit_ptr ))
  2714.       *global_topo_ptr++ = unit_ptr;  /*  save output unit  */
  2715.  
  2716.   /*  limit right side of the topologic array with NULL pointer  */
  2717.   *global_topo_ptr++ = NULL;
  2718.  
  2719.   /*  calc. no. of sorted units  */
  2720.   no_of_topo_units = (global_topo_ptr - topo_ptr_array) - 4;
  2721.  
  2722.   /*  search for dead units i.e. units without inputs  */
  2723.   FOR_ALL_UNITS( unit_ptr )
  2724.     if (!(unit_ptr->flags & UFLAG_REFRESH) && UNIT_IN_USE( unit_ptr ))
  2725.       {
  2726.       topo_msg.no_of_dead_units++;
  2727.       if (topo_msg.src_error_unit == 0)
  2728.         topo_msg.src_error_unit = unit_ptr - unit_array;  /*  store unit no.  */
  2729.     }
  2730.  
  2731.   if (topo_msg.no_of_dead_units != 0)
  2732.     KernelErrorCode = KRERR_DEAD_UNITS;
  2733.  
  2734.   return( KernelErrorCode );
  2735. }
  2736.  
  2737.  
  2738. /*****************************************************************************
  2739.   FUNCTION : kr_topoSortIHO
  2740.  
  2741.   PURPOSE  : Sort units by their topologic type, i.e. Input, Hidden, Output 
  2742.              units and stores the pointers to this units in the topologic array.
  2743.   NOTES    : 
  2744.  
  2745.   RETURNS  : error code 
  2746.   UPDATE   : 
  2747. ******************************************************************************/
  2748. static krui_err  kr_topoSortIHO(void)
  2749. {
  2750.   TopoPtrArray     topo_ptr;
  2751.   register struct Unit   *unit_ptr;
  2752.   int  no_of_units;
  2753.   int has_no_dual;
  2754.  
  2755.  
  2756.   KernelErrorCode = KRERR_NO_ERROR;  /*  reset return code  */
  2757.   topo_ptr = topo_ptr_array;
  2758.  
  2759.   /*  limit left side of the topological array with NULL pointer  */
  2760.   *topo_ptr++ = NULL;
  2761.  
  2762.   /*  get input units  */
  2763.   no_of_units = 0;
  2764.   FOR_ALL_UNITS( unit_ptr )
  2765.     if (IS_INPUT_UNIT( unit_ptr ) && UNIT_IN_USE( unit_ptr ))
  2766.       {
  2767.       *topo_ptr++ = unit_ptr;
  2768.       no_of_units++;
  2769.     }
  2770.  
  2771.  
  2772.   if ((NoOfInputUnits = no_of_units) == 0)
  2773.     {
  2774.     KernelErrorCode = KRERR_NO_INPUT_UNITS;
  2775.     return( KernelErrorCode );
  2776.   }
  2777.  
  2778.   /*  limit input units in the topological array with NULL pointer  */
  2779.   *topo_ptr++ = NULL;
  2780.  
  2781.   /*  get hidden units  */
  2782.   no_of_units = 0;
  2783.   FOR_ALL_UNITS( unit_ptr )
  2784.     if (IS_HIDDEN_UNIT( unit_ptr ) && UNIT_IN_USE( unit_ptr ))
  2785.       {
  2786.       *topo_ptr++ = unit_ptr;
  2787.       no_of_units++;
  2788.     }
  2789.  
  2790.   if ((NoOfHiddenUnits = no_of_units) == 0)
  2791.     {
  2792.     /* In special case for DUAL units */ 
  2793.     FOR_ALL_UNITS( unit_ptr )
  2794.       if (IS_DUAL_UNIT( unit_ptr ) )
  2795.         has_no_dual = FALSE;
  2796.     if ( has_no_dual ){ 
  2797.     KernelErrorCode = KRERR_NO_HIDDEN_UNITS;
  2798.     return( KernelErrorCode );
  2799.     }
  2800.   }
  2801.  
  2802.   /*  limit hidden units in the topological array with NULL pointer  */
  2803.   *topo_ptr++ = NULL;
  2804.  
  2805.   /*  get output units  */
  2806.   no_of_units = 0;
  2807.   FOR_ALL_UNITS( unit_ptr )
  2808.     if (IS_OUTPUT_UNIT( unit_ptr ) && UNIT_IN_USE( unit_ptr ))
  2809.       {
  2810.       *topo_ptr++ = unit_ptr;
  2811.       no_of_units++;
  2812.     }
  2813.  
  2814.   if ((NoOfOutputUnits = no_of_units) == 0)
  2815.     {
  2816.     KernelErrorCode = KRERR_NO_OUTPUT_UNITS;
  2817.     return( KernelErrorCode );
  2818.   }
  2819.  
  2820.   /*  limit right side of the topologic array with NULL pointer  */
  2821.   *topo_ptr++ = NULL;
  2822.  
  2823.   /*  calc. no. of sorted units  */
  2824.   no_of_topo_units = (topo_ptr - topo_ptr_array) - 4;
  2825.  
  2826.   return( KernelErrorCode );
  2827. }
  2828.  
  2829. /*****************************************************************************
  2830.   FUNCTION : kr_topoSortLOG() 
  2831.  
  2832.   PURPOSE  : Sort units by their logical Layer- and Unitnumber
  2833.  
  2834.   NOTES    : 
  2835.  
  2836.   RETURNS  : error code 
  2837.   UPDATE   : 
  2838. ******************************************************************************/
  2839.  
  2840. static int llncompare(const struct Unit **a, const struct Unit **b)
  2841.   int llndiff, lundiff;
  2842.  
  2843.   llndiff = ((*a)->lln - (*b)->lln);
  2844.   lundiff = ((*a)->lun - (*b)->lun);
  2845.   return(llndiff != 0 ? llndiff : lundiff);
  2846. }
  2847.  
  2848. static krui_err  kr_topoSortLOG(void)
  2849. {
  2850.   struct Unit      *unit_ptr;
  2851.   TopoPtrArray     topo_ptr;
  2852.   TopoPtrArray     topo_ptr_save;
  2853.   int              no_of_units = 0;
  2854.  
  2855.   topo_ptr = topo_ptr_array;
  2856.   *topo_ptr++ = (struct Unit *) NULL;
  2857.  
  2858.   
  2859.   FOR_ALL_UNITS( unit_ptr )
  2860.     if ( (unit_ptr->flags & UFLAG_IN_USE) == UFLAG_IN_USE) 
  2861.       {
  2862.       *topo_ptr = unit_ptr;
  2863.       topo_ptr++;
  2864.       no_of_units++;
  2865.       }
  2866.   *topo_ptr = (struct Unit *) NULL;
  2867.   topo_ptr_save = topo_ptr;
  2868.  
  2869.   no_of_topo_units = no_of_units;
  2870.   topo_ptr = topo_ptr_array;
  2871.   topo_ptr++;
  2872.   qsort(topo_ptr, no_of_units, sizeof(*topo_ptr), 
  2873.     (int (*)(const void *, const void *)) llncompare);
  2874.  
  2875.   /* insert NULL pointer between input units and rest */
  2876.   topo_ptr = topo_ptr_save;
  2877.   while (*topo_ptr == (struct Unit *) NULL ||
  2878.          !(IS_INPUT_UNIT(*topo_ptr)))
  2879.   {
  2880.       *(topo_ptr + 1) = *topo_ptr;
  2881.       topo_ptr--;
  2882.   }
  2883.   topo_ptr++;
  2884.   *topo_ptr = (struct Unit *) NULL;
  2885.   topo_ptr_save++;
  2886.  
  2887.   /* insert NULL pointer between output units and rest */
  2888.   topo_ptr = topo_ptr_save;
  2889.   while (*topo_ptr == (struct Unit *) NULL ||
  2890.          (IS_OUTPUT_UNIT(*topo_ptr)))
  2891.   {
  2892.       *(topo_ptr + 1) = *topo_ptr;
  2893.       topo_ptr--;
  2894.   }
  2895.   topo_ptr++;
  2896.   *topo_ptr = (struct Unit *) NULL;
  2897.   topo_ptr_save++;
  2898.  
  2899.   /* create pointers from units to topo_ptr_array */
  2900.   topo_ptr = topo_ptr_array;
  2901.   while (topo_ptr != topo_ptr_save)
  2902.   {
  2903.       if (*topo_ptr != (struct Unit *) NULL)
  2904.       {
  2905.           (*topo_ptr) -> TD.my_topo_ptr = topo_ptr;
  2906.       }
  2907.       topo_ptr++;
  2908.   }
  2909.   return (KRERR_NO_ERROR);
  2910. }
  2911.  
  2912.  
  2913. /*****************************************************************************
  2914.   FUNCTION : kr_topoSort
  2915.  
  2916.   PURPOSE  : 
  2917.  
  2918.     Sort units according to the given mode:
  2919.     TOPOLOGICAL:
  2920.       Sort units topological (general version) and stores the
  2921.       pointers to this units in the topologic array.
  2922.       NOTE: Units are not sorted by their topologic type (that's not
  2923.         possible in general case).
  2924.  
  2925.     TOPOLOGICAL_FF:
  2926.       Sorts unit topological in feed-forward networks and stores the
  2927.       pointers to this units in the topologic array in the following order:
  2928.        - input,
  2929.        - hidden and
  2930.        - output units
  2931.  
  2932.       This function make following assumtions (like all learning functions for
  2933.       feed-forward networks):
  2934.        a) input units doesn't have input connections to other units and
  2935.        b) output units doesn't have outputs connections to other units.
  2936.  
  2937.     TOPOLOGIC_TYPE:
  2938.       Sort units by their topologic type, i.e. Input, Hidden, Output units and
  2939.       stores the pointers to this units in the topologic array.
  2940.  
  2941.     TOPOLOGIC_LOGICAL:
  2942.       Sort Units according to their logical Layers- and Unitsnumbers.
  2943.       The entry TD.my_topo_ptr in every unit is set to point to coresponding
  2944.       entry in the topo_ptr_array.
  2945.  
  2946.     ART1_TOPO_TYPE:
  2947.       Sort units in ART1 manner. For informations about the structure of
  2948.       ART1 networks see Diplomarbeit No.929; Kai-Uwe Herrmann; University of
  2949.       Stuttgart; Germany 1992. The pointers are sorted as follows:
  2950.  
  2951.       NULL, pointers to input units, NULL, pointers to comparison units,
  2952.       NULL, pointers to recognition units, NULL, pointers to delay units,
  2953.       NULL, pointers to local reset units, NULL, pointers to special units,
  2954.       NULL, NULL, ...
  2955.  
  2956.     ART2_TOPO_TYPE:
  2957.       Sort units in ART2 manner. For informations about the structure of
  2958.       ART2 networks see Diplomarbeit No.929; Kai-Uwe Herrmann; University of
  2959.       Stuttgart; Germany 1992. The pointers are sorted as follows:
  2960.  
  2961.       NULL, pointers to input units, NULL, pointers to w units,
  2962.       NULL, pointers to x units, NULL, pointers to u units,
  2963.       NULL, pointers to v units, NULL, pointers to p units,
  2964.       NULL, pointers to q units, NULL, pointers to r units,
  2965.       NULL, pointers to recognition units, NULL, pointers to delay units,
  2966.       NULL, pointers to local reset units, NULL, pointers to special units,
  2967.       NULL, NULL, ...
  2968.  
  2969.     ARTMAP_TOPO_TYPE:
  2970.       Sort units in ARTMAP manner. For informations about the structure of
  2971.       ARTMAP networks see Diplomarbeit No.929; Kai-Uwe Herrmann; University of
  2972.       Stuttgart; Germany 1992. The pointers are sorted as follows:
  2973.  
  2974.       NULL, ARTa inp units, NULL, ARTa cmp units, NULL, ARTa rec units ...,
  2975.       NULL, ARTb inp units, NULL, ARTb cmp units, NULL, ARTb rec units ...,
  2976.       NULL, map field units, NULL, map field special units, NULL
  2977.  
  2978.   NOTES    : 
  2979.  
  2980.   RETURNS  : error code 
  2981.   UPDATE   : 
  2982. ******************************************************************************/
  2983. krui_err  kr_topoSort(int topo_sorting_mode)
  2984. {
  2985.   KernelErrorCode = KRERR_NO_ERROR;  /*  reset return code  */
  2986.   TopoSortID = NOT_SORTED;
  2987.   if (NoOfUnits == 0)
  2988.     {  /*  No units defined  */
  2989.     KernelErrorCode = KRERR_NO_UNITS;
  2990.     return( KernelErrorCode );
  2991.   }
  2992.  
  2993.  
  2994.   if (krm_allocUnitTopoArray( NoOfUnits + 15) != KRERR_NO_ERROR)
  2995.     return( KernelErrorCode );
  2996.  
  2997.   /*  clear error codes  */
  2998.   topo_msg.no_of_cycles = topo_msg.no_of_dead_units =
  2999.   topo_msg.dest_error_unit = topo_msg.src_error_unit = 0;
  3000.   topo_msg.error_code = KRERR_NO_ERROR;
  3001.  
  3002.   switch (topo_sorting_mode)
  3003.     {
  3004.     case  TOPOLOGICAL:
  3005.     (void) kr_topoSortT();
  3006.     break;
  3007.     case  TOPOLOGICAL_FF:
  3008.     (void) kr_topoSortFF();
  3009.     break;
  3010.     case  TOPOLOGIC_TYPE:
  3011.     (void) kr_topoSortIHO();
  3012.     break;
  3013.     case  TOPOLOGIC_LOGICAL:
  3014.         KernelErrorCode = kr_topoSortLOG();
  3015.         break;
  3016.     case  ART1_TOPO_TYPE:
  3017.         KernelErrorCode = kra1_sort ();
  3018.         break;
  3019.  
  3020.     case ART2_TOPO_TYPE:
  3021.         KernelErrorCode = kra2_sort ();
  3022.         break;
  3023.  
  3024.     case ARTMAP_TOPO_TYPE:
  3025.         KernelErrorCode = kram_sort ();
  3026.         break;
  3027.     case TOPOLOGICAL_CC:
  3028.         (void) cc_topoSort(TOPOLOGICAL_CC);
  3029.         break; 
  3030.     case TOPOLOGICAL_RCC:
  3031.         (void) cc_topoSort(TOPOLOGICAL_RCC);
  3032.         break; 
  3033.     case TOPOLOGICAL_BCC:
  3034.         (void) cc_topoSort(TOPOLOGICAL_BCC);
  3035.         break;
  3036.     case TOPOLOGICAL_JE:
  3037.     KernelErrorCode = kr_topoSortJE () ;
  3038.     break ;
  3039.  
  3040.     default:
  3041.     KernelErrorCode = KRERR_TOPOMODE;
  3042.     }
  3043.  
  3044.   if ((KernelErrorCode == KRERR_NO_ERROR) || 
  3045.       (KernelErrorCode == KRERR_DEAD_UNITS))
  3046.     TopoSortID = topo_sorting_mode;
  3047.  
  3048.   return( KernelErrorCode );
  3049. }
  3050.  
  3051.  
  3052.  
  3053. /*****************************************************************************
  3054.   FUNCTION : kr_topoCheck
  3055.  
  3056.   PURPOSE  : Checks the topology of the network:
  3057.              a) counts the number of layers of the network and
  3058.          b) determines if the network has cycles.
  3059.   NOTES    : 
  3060.  
  3061.   RETURNS  : Returns the no. of layers of the network.
  3062.   UPDATE   : 
  3063. ******************************************************************************/
  3064. int  kr_topoCheck(void)
  3065. {
  3066.   struct Unit   *unit_ptr;
  3067.   bool      o_units;
  3068.  
  3069.  
  3070.   topo_msg.no_of_cycles = topo_msg.no_of_dead_units =
  3071.   topo_msg.dest_error_unit = topo_msg.src_error_unit =
  3072.   topo_msg.no_of_layers = 0;
  3073.   topo_msg.error_code = KernelErrorCode = KRERR_NO_ERROR;
  3074.  
  3075.   if (NoOfUnits == 0)
  3076.     {  /*  no units defined  */
  3077.     KernelErrorCode = KRERR_NO_UNITS;
  3078.     return( KernelErrorCode );
  3079.   }
  3080.  
  3081.   clr_T_flags();    /*    reset units 'touch' flags  */
  3082.  
  3083.   /*  begin depth search at the first output unit  */
  3084.   o_units = FALSE;
  3085.   FOR_ALL_UNITS( unit_ptr )
  3086.     if ( IS_OUTPUT_UNIT( unit_ptr ) && UNIT_IN_USE( unit_ptr ) )
  3087.       {
  3088.       o_units = TRUE;
  3089.       DepthFirst2( unit_ptr, 1 );
  3090.       if (topo_msg.error_code != KRERR_NO_ERROR)
  3091.         {  /*  stop if an error occured  */
  3092.         KernelErrorCode = topo_msg.error_code;
  3093.         return( KernelErrorCode );
  3094.       }
  3095.     }
  3096.       
  3097.   if (!o_units)
  3098.     {  /*  no output units */
  3099.     KernelErrorCode = KRERR_NO_OUTPUT_UNITS;
  3100.     return( KernelErrorCode );
  3101.   }
  3102.  
  3103.   /*  return the no. of layers of the network  */
  3104.   return( topo_msg.no_of_layers );
  3105. }
  3106.  
  3107. /*****************************************************************************
  3108.   FUNCTION : kr_makeUnitPermutation
  3109.  
  3110.   PURPOSE  : 
  3111.   NOTES    : 
  3112.  
  3113.   RETURNS  : Returns error code
  3114.   UPDATE   : 
  3115. ******************************************************************************/
  3116. krui_err  kr_makeUnitPermutation(void)
  3117. {
  3118.   register struct Unit   *unit_ptr;
  3119.   register int       no_of_units, i;
  3120.   TopoPtrArray     topo_ptr,  t_ptr1,  t_ptr2;
  3121.  
  3122.  
  3123.   TopoSortID = NOT_SORTED;
  3124.   if (NoOfUnits == 0)  return( KRERR_NO_UNITS );  /*  no units defined    */
  3125.  
  3126.   if ( krm_allocUnitTopoArray( NoOfUnits + 2) != 0)
  3127.     return( KRERR_INSUFFICIENT_MEM );
  3128.  
  3129.   topo_ptr = topo_ptr_array;
  3130.  
  3131.   /*  limit left side of the topological array with NULL pointer  */
  3132.   *topo_ptr++ = NULL;
  3133.  
  3134.   /*  initialize permutation array  */
  3135.   FOR_ALL_UNITS( unit_ptr )
  3136.     if ( (unit_ptr->flags & UFLAG_INITIALIZED) == UFLAG_INITIALIZED)
  3137.       /*  unit is in use and enabled  */
  3138.       *topo_ptr++ = unit_ptr;
  3139.  
  3140.   no_of_topo_units = topo_ptr - topo_ptr_array;  /* calc no. of sorted units */
  3141.   no_of_units = no_of_topo_units;
  3142.  
  3143.   topo_ptr = topo_ptr_array;
  3144.   /*  permutate unit order  */
  3145.   for (i = 0; i < no_of_units; i++)
  3146.     {
  3147.     t_ptr1 = topo_ptr + (lrand48() % no_of_units);
  3148.     t_ptr2 = topo_ptr + (lrand48() % no_of_units);
  3149.  
  3150.     unit_ptr = *t_ptr1;
  3151.     *t_ptr1 = *t_ptr2;
  3152.     *t_ptr2 = unit_ptr;
  3153.     }
  3154.  
  3155.   /*  limit right side of the topologic array with NULL pointer  */
  3156.   *topo_ptr++ = NULL;
  3157.  
  3158.   TopoSortID = PERMUTATION;
  3159.   NetModified = FALSE;
  3160.  
  3161.   return( KRERR_NO_ERROR );
  3162. }
  3163.  
  3164.  
  3165. /*#################################################
  3166.  
  3167. GROUP: Functions for pattern management
  3168.  
  3169. #################################################*/
  3170. /*****************************************************************************
  3171.   FUNCTION : kr_IOCheck
  3172.  
  3173.   PURPOSE  :  Count the no. of input and output units and return an error code
  3174.               if the no. do not fit to the loaded patterns.
  3175.   NOTES    : 
  3176.  
  3177.   RETURNS  : Returns error code
  3178.   UPDATE   : 
  3179. ******************************************************************************/
  3180. krui_err  kr_IOCheck(void)
  3181. {
  3182.   register struct Unit   *unit_ptr;
  3183.   register int  no_of_i_units, no_of_o_units;
  3184.  
  3185.   KernelErrorCode = KRERR_NO_ERROR;  /*  reset return code  */
  3186.  
  3187.   /*  count no. of input and output units  */
  3188.   no_of_i_units = no_of_o_units = 0;
  3189.   FOR_ALL_UNITS( unit_ptr )
  3190.     if UNIT_IN_USE( unit_ptr ){
  3191.       if IS_INPUT_UNIT( unit_ptr )
  3192.         no_of_i_units++;
  3193.       if IS_OUTPUT_UNIT( unit_ptr )
  3194.           no_of_o_units++;
  3195.     }
  3196.   NoOfInputUnits = no_of_i_units;
  3197.   NoOfOutputUnits = no_of_o_units;
  3198.  
  3199.   return( KernelErrorCode );
  3200. }
  3201.  
  3202. /*#################################################
  3203.  
  3204. GROUP: other functions
  3205.  
  3206. #################################################*/
  3207.  
  3208.   
  3209.  
  3210. /*#################################################
  3211.  
  3212. GROUP: Functions for handeling network propagation,
  3213.        update and learning functions.
  3214.  
  3215. #################################################*/
  3216. /*****************************************************************************
  3217.   FUNCTION : kr_callNetworkFunctionSTD
  3218.  
  3219.   PURPOSE  : calls the current network function
  3220.   NOTES    : 
  3221.  
  3222.   RETURNS  : Returns error code
  3223.   UPDATE   : 
  3224. ******************************************************************************/
  3225. static krui_err  kr_callNetworkFunctionSTD(int type, float *parameterInArray, 
  3226.                        int NoOfInParams, 
  3227.                        float **parameterOutArray, 
  3228.                        int *NoOfOutParams, 
  3229.                        int start_pattern, int end_pattern)
  3230. {
  3231.   FunctionPtr  func_ptr;
  3232.   NetFunctionPtr  net_func_ptr;
  3233.   char  *curr_func;
  3234.   int size;
  3235.  
  3236.  
  3237.   if ( (curr_func = krf_getCurrentNetworkFunc( type )) == NULL)
  3238.     return( KernelErrorCode );
  3239.   if (!krf_funcSearch( curr_func, type, &func_ptr ) )
  3240.     return( KernelErrorCode );
  3241.  
  3242.   KernelErrorCode = KRERR_NO_ERROR;
  3243.   net_func_ptr = (NetFunctionPtr) func_ptr;
  3244.  
  3245.   switch (type)  {
  3246.     case  UPDATE_FUNC:
  3247.       KernelErrorCode = 
  3248.       (*(UpdateFuncPtr)net_func_ptr) ( parameterInArray, NoOfInParams );
  3249.       return( KernelErrorCode );
  3250.  
  3251.     case  LEARN_FUNC:
  3252.       if (kr_TotalNoOfPattern() == 0)
  3253.     {  /*  no patterns defined  */
  3254.     KernelErrorCode = KRERR_NO_PATTERNS;
  3255.     return( KernelErrorCode );
  3256.       }
  3257.       if ((start_pattern < 0) || (end_pattern >= kr_TotalNoOfPattern()) )
  3258.     {  /*  Invalid pattern number  */
  3259.     KernelErrorCode = KRERR_PATTERN_NO;
  3260.     return( KernelErrorCode );
  3261.       }
  3262.  
  3263.       /* check whether sub pattern fits onto network */
  3264.       if (NetModified)
  3265.       kr_IOCheck();
  3266.       size = kr_SizeOfInputSubPat();
  3267.       if (NoOfInputUnits != size)
  3268.       {
  3269.       if (size < 0)
  3270.           KernelErrorCode = size;
  3271.       else
  3272.           KernelErrorCode = KRERR_NP_DOES_NOT_FIT;
  3273.       return KernelErrorCode;
  3274.       }
  3275.       size = kr_SizeOfOutputSubPat();
  3276.       if (NoOfOutputUnits != size)
  3277.       {
  3278.       if (size < 0)
  3279.           KernelErrorCode = size;
  3280.       else if (size == 0)
  3281.           KernelErrorCode = KRERR_NP_NO_OUTPUT_PATTERN;
  3282.       else
  3283.           KernelErrorCode = KRERR_NP_DOES_NOT_FIT;
  3284.       return KernelErrorCode;
  3285.       }
  3286.  
  3287.       /*  call current learning function  */
  3288.       KernelErrorCode = 
  3289.       (*(LearnFuncPtr)net_func_ptr) (start_pattern, end_pattern,
  3290.                      parameterInArray, NoOfInParams,
  3291.                      parameterOutArray, NoOfOutParams);
  3292.  
  3293.       if (KernelErrorCode == KRERR_NO_ERROR)
  3294.     {  /*  learning function has initialized the network  */
  3295.     NetInitialize = FALSE;
  3296.     LearnFuncHasChanged = FALSE;
  3297.       }
  3298.  
  3299.       return( KernelErrorCode );
  3300.  
  3301.     case  INIT_FUNC:
  3302.       NetInitialize = TRUE;
  3303.       KernelErrorCode = 
  3304.       (*(InitFuncPtr)net_func_ptr) ( parameterInArray, NoOfInParams );
  3305.  
  3306.       return( KernelErrorCode );
  3307.  
  3308.    default:
  3309.      KernelErrorCode = KRERR_PARAMETERS;
  3310.      return( KernelErrorCode );
  3311.   }
  3312. }
  3313.  
  3314. /*****************************************************************************
  3315.   FUNCTION : kr_callNetworkFunction
  3316.  
  3317.   PURPOSE  : calls the current network function
  3318.   NOTES    : 
  3319.  
  3320.   RETURNS  : Returns error code
  3321.   UPDATE   : 
  3322. ******************************************************************************/
  3323. krui_err  kr_callNetworkFunction(int type, float *parameterInArray, 
  3324.                  int NoOfInParams, float **parameterOutArray, 
  3325.                  int *NoOfOutParams, int start_pattern, 
  3326.                  int end_pattern)
  3327. {
  3328.   krui_err dummy;
  3329.   if (NoOfUnits == 0)
  3330.     {  /*  No Units defined  */
  3331.     KernelErrorCode = KRERR_NO_UNITS;
  3332.     return( KRERR_NO_UNITS );
  3333.   }
  3334.  
  3335.   KernelErrorCode = KRERR_NO_ERROR;
  3336.  
  3337.   switch (specialNetworkType)  {
  3338.     case NET_TYPE_GENERAL:
  3339.       /*  normal network presentation  */
  3340.       /*  the result of this call has been void which is not compatible */
  3341.       /*  to the declaration; therefor the dummy error variable is included */
  3342.       dummy = kr_callNetworkFunctionSTD( type, parameterInArray, NoOfInParams,
  3343.                                         parameterOutArray, NoOfOutParams,
  3344.                                         start_pattern, end_pattern );
  3345.       break;
  3346.  
  3347. #ifdef MASPAR_KERNEL
  3348.   static struct NetFuncParameters  net_func_params;
  3349.  
  3350.     case NET_TYPE_FF1:
  3351. #ifndef MASPAR_KERNEL_EMULATION
  3352.  
  3353.       /*  feedforward net on MasPar  */
  3354.       net_func_params.start_pattern_no = start_pattern;
  3355.       net_func_params.end_pattern_no   = end_pattern;
  3356.       net_func_params.no_of_input_parameters = NoOfInParams;
  3357.  
  3358.       memcpy( net_func_params.input_parameters, parameterInArray,
  3359.               sizeof (float) * NoOfInParams );
  3360.  
  3361.       (void) krff_callMasParNetworkFunction( type, &net_func_params );
  3362.  
  3363.       if (NoOfOutParams != NULL)
  3364.         *NoOfOutParams = net_func_params.no_of_output_parameters;
  3365.       if (parameterOutArray != NULL)
  3366.         *parameterOutArray = net_func_params.output_parameters;
  3367.  
  3368. #else
  3369.       KernelErrorCode = KRERR_NOT_IMPEMENTED_YET;
  3370. #endif
  3371.  
  3372.       break;
  3373. #endif
  3374.  
  3375.     default:
  3376.       KernelErrorCode = KRERR_PARAMETERS;
  3377.   }
  3378.  
  3379.   return( KernelErrorCode );
  3380. }
  3381.  
  3382. #ifdef KERNEL3D
  3383.  
  3384. #ifdef HAVE_QSORT
  3385. static int  transTableCompare( const void *node1, const void *node2)
  3386. {
  3387.   short  z1, z2;
  3388.  
  3389.   z1=((struct TransTable *) node1)->z;
  3390.   z2=((struct TransTable *) node2)->z;
  3391.  
  3392.   if (z1 < z2)  return -1;
  3393.   if (z1 > z2)  return 1;
  3394.   return 0;
  3395. }
  3396. #endif
  3397.  
  3398. krui_err  kr_xyTransTable(int op, int *x, int *y, int z)
  3399. {
  3400.   struct TransTable  *transTablePtr,
  3401.                      *new_transTable,
  3402.                      transTableEntry;
  3403.  
  3404.  
  3405.   switch(op)  {
  3406.     case OP_TRANSTABLE_GET:
  3407.       if (transTable != NULL)  {
  3408.  
  3409. #ifdef HAVE_QSORT
  3410.         transTableEntry.z = z;
  3411.         transTablePtr = 
  3412.         (struct TransTable *) bsearch( &transTableEntry,
  3413.                       (struct TransTable *) transTable,
  3414.                       transTableSize,
  3415.                       sizeof(struct TransTable),
  3416.                       transTableCompare );
  3417. #else
  3418.     for (transTablePtr = transTable;
  3419.              transTablePtr < (transTable + transTableSize);
  3420.              transTablePtr++)
  3421.           if (transTablePtr->z == z)  break;
  3422.  
  3423.           if (transTablePtr == (transTable + transTableSize))
  3424.             transTablePtr=NULL;
  3425. #endif
  3426.  
  3427.         if (transTablePtr == NULL)  {
  3428.           *x=*y=0;
  3429.         }
  3430.         else  {
  3431.           *x=transTablePtr->x;
  3432.           *y=transTablePtr->y;
  3433.         }
  3434.       }
  3435.       else  {
  3436.         *x=*y=0;
  3437.       }
  3438.  
  3439.       KernelErrorCode=KRERR_NO_ERROR;
  3440.       return( KRERR_NO_ERROR );
  3441.  
  3442.     case OP_TRANSTABLE_SET:
  3443.       if (transTable == NULL)  {
  3444.         if((new_transTable =
  3445.            (struct TransTable *) malloc( sizeof(struct TransTable) )) == NULL){
  3446.           KernelErrorCode=KRERR_INSUFFICIENT_MEM;
  3447.           return( KRERR_INSUFFICIENT_MEM );
  3448.         }
  3449.  
  3450.         transTable=new_transTable;
  3451.  
  3452.         transTable->z = z;
  3453.         transTable->x = *x;
  3454.         transTable->y = *y;
  3455.         transTableSize=1;
  3456.       }
  3457.       else  {
  3458. #ifdef HAVE_QSORT
  3459.         transTableEntry.z = z;
  3460.         transTablePtr = 
  3461.         (struct TransTable *) bsearch( &transTableEntry,
  3462.                       (struct TransTable *) transTable,
  3463.                       transTableSize,
  3464.                       sizeof(struct TransTable),
  3465.                       transTableCompare );
  3466. #else
  3467.         for (transTablePtr = transTable;
  3468.              transTablePtr < (transTable + transTableSize);
  3469.              transTablePtr++)
  3470.           if (transTablePtr->z == z)  break;
  3471.  
  3472.           if (transTablePtr == (transTable + transTableSize))
  3473.             transTablePtr=NULL;
  3474. #endif
  3475.  
  3476.         if (transTablePtr == NULL)  {
  3477.           if ((new_transTable = 
  3478.            (struct TransTable *) realloc( (void *) transTable,
  3479.         sizeof(struct TransTable) * (transTableSize + 1) )) == NULL)  {
  3480.             KernelErrorCode=KRERR_INSUFFICIENT_MEM;
  3481.             return( KRERR_INSUFFICIENT_MEM );
  3482.           }
  3483.  
  3484.           transTable=new_transTable;
  3485.  
  3486.           transTable[transTableSize].z = z;
  3487.           transTable[transTableSize].x = *x;
  3488.           transTable[transTableSize].y = *y;
  3489.           ++transTableSize;
  3490.  
  3491. #ifdef HAVE_QSORT
  3492.           qsort( (struct TransTable *) transTable,
  3493.                  transTableSize,
  3494.                  sizeof(struct TransTable),
  3495.                  transTableCompare );
  3496. #endif
  3497.         }
  3498.         else  {
  3499.           transTablePtr->x = *x;
  3500.           transTablePtr->y = *y;
  3501.         }
  3502.       }
  3503.  
  3504.       KernelErrorCode=KRERR_NO_ERROR;
  3505.       return( KRERR_NO_ERROR );
  3506.  
  3507.     case OP_TRANSTABLE_CLEAR:
  3508.       if (transTable != NULL)  {
  3509.         free( (void *) transTable );
  3510.         transTable = NULL;
  3511.         transTableSize = 0;
  3512.       }
  3513.  
  3514.       KernelErrorCode=KRERR_NO_ERROR;
  3515.       return( KRERR_NO_ERROR );
  3516.  
  3517.     default:
  3518.       KernelErrorCode=KRERR_PARAMETERS;
  3519.       return( KRERR_PARAMETERS );
  3520.   }
  3521. }
  3522.  
  3523. #endif
  3524.  
  3525. /*#################################################
  3526.  
  3527. GROUP: Functions for the parallel kernel
  3528.  
  3529. #################################################*/
  3530.  
  3531. /*****************************************************************************
  3532.   FUNCTION : kr_setSpecialNetworkType
  3533.  
  3534.   PURPOSE  : Sets the topologic type of the current network and checks the 
  3535.              topology of the current network.
  3536.          Returns an error if the topologic type of the current network  
  3537.          doesn't fit to this type.
  3538.          Topologic types are:
  3539.          - NET_TYPE_GENERAL
  3540.          general purpose network type with no limitations
  3541.          - NET_TYPE_FF1
  3542.          feedforward network with fully connected units in
  3543.          neighbour layers
  3544.   NOTES    : 
  3545.  
  3546.   RETURNS  : Returns error code
  3547.   UPDATE   : 
  3548. ******************************************************************************/
  3549. krui_err  kr_setSpecialNetworkType(int net_type)
  3550. {
  3551.   KernelErrorCode = KRERR_NO_ERROR;
  3552.  
  3553.   if (net_type == specialNetworkType)  return( KRERR_NO_ERROR );
  3554.  
  3555.   if (NoOfUnits == 0)
  3556.     {  /*  no units defined  */
  3557.     KernelErrorCode = KRERR_NO_UNITS;
  3558.     return( KernelErrorCode );
  3559.   }
  3560.  
  3561.   switch (net_type)  {
  3562.     case  NET_TYPE_GENERAL:
  3563.  
  3564.       switch (specialNetworkType)  {
  3565.         case  NET_TYPE_FF1:
  3566.           /*  change special network presentation to standard presentation  */
  3567.  
  3568. #ifdef  MASPAR_KERNEL
  3569.           (void) krff_standardNetPresentationFF1();
  3570.           specialNetworkType = NET_TYPE_GENERAL;
  3571. #else
  3572.           KernelErrorCode = KRERR_NO_MASPAR_KERNEL;
  3573. #endif
  3574.           break;
  3575.  
  3576.         default:
  3577.           KernelErrorCode = KRERR_PARAMETERS;
  3578.       }
  3579.  
  3580.       break;
  3581.  
  3582.     case  NET_TYPE_FF1:
  3583.       /*  change standart network presentation to special presentation  */
  3584. #ifdef  MASPAR_KERNEL
  3585.       (void) krff_determineNetFF1Params();
  3586.       /*  change internal network presentation    */
  3587.       if (KernelErrorCode != KRERR_NO_ERROR)  break;
  3588.  
  3589.       (void) krff_initMasPar();
  3590.       if (KernelErrorCode != KRERR_NO_ERROR)  break;
  3591.  
  3592.       (void) krff_changeNetPresentationFF1();
  3593.  
  3594. #else
  3595.       KernelErrorCode = KRERR_NO_MASPAR_KERNEL;
  3596. #endif
  3597.       break;
  3598.  
  3599.     default:
  3600.       KernelErrorCode = KRERR_PARAMETERS;
  3601.   }
  3602.  
  3603.   if (KernelErrorCode == KRERR_NO_ERROR)
  3604.     specialNetworkType = net_type;
  3605.  
  3606.   return( KernelErrorCode );
  3607. }
  3608.  
  3609. /*****************************************************************************
  3610.   FUNCTION : kr_getSpecialNetworkType
  3611.  
  3612.   PURPOSE  : Returns the special topologic type of the current network, if set.
  3613.   NOTES    : 
  3614.  
  3615.   RETURNS  : Returns the special topologic type of the current network, if set.
  3616.   UPDATE   : 
  3617. ******************************************************************************/
  3618. int  kr_getSpecialNetworkType(void)
  3619. {
  3620.   return( specialNetworkType );
  3621. }
  3622.  
  3623.  
  3624. /*****************************************************************************
  3625.   FUNCTION : kr_validateOperation
  3626.  
  3627.   PURPOSE  : Validate a network modifying operation according to
  3628.              the kernel mode 
  3629.   NOTES    : 
  3630.  
  3631.   RETURNS  : error code
  3632.   UPDATE   : 
  3633. ******************************************************************************/
  3634. krui_err  kr_validateOperation(void)
  3635. {
  3636.   switch (specialNetworkType)
  3637.     {
  3638.     case NET_TYPE_GENERAL:
  3639.       /*  normal network presentation, no limitations  */
  3640.       KernelErrorCode = KRERR_NO_ERROR;
  3641.       break;
  3642.     case NET_TYPE_FF1:
  3643.       /*  feedforward net with limitations  */
  3644.       KernelErrorCode = KRERR_MODE_FF1_INVALID_OP;
  3645.       break;
  3646.   }
  3647.  
  3648.   return( KernelErrorCode );
  3649. }
  3650.  
  3651.  
  3652. /* #############################################################
  3653.  
  3654.   Functions for the MasPar kernel
  3655.  
  3656. ############################################################# */
  3657.  
  3658. #ifdef  MASPAR_KERNEL
  3659. /*****************************************************************************
  3660.   FUNCTION : kr_initMasPar
  3661.  
  3662.   PURPOSE  : Connects and Disconnects the MasPar.
  3663.              The mode switches are:  MASPAR_CONNECT and MASPAR_DISCONNECT.
  3664.   NOTES    : 
  3665.  
  3666.   RETURNS  : error code
  3667.   UPDATE   : 
  3668. ******************************************************************************/
  3669. krui_err  kr_initMasPar(int mode )
  3670. {
  3671.   if (specialNetworkType == NET_TYPE_GENERAL)  {
  3672.     KernelErrorCode = KRERR_NOT_PARALLEL_MODE;
  3673.     return( KernelErrorCode );
  3674.   }
  3675.  
  3676.   KernelErrorCode = KRERR_NO_ERROR;
  3677.  
  3678.   switch (mode)
  3679.     {
  3680.     case  MASPAR_CONNECT:
  3681.       /*  connect maspar  */
  3682.       if (krff_initMasPar() == KRERR_NO_ERROR)
  3683.         masParStatus = MASPAR_CONNECT;
  3684.  
  3685.       break;
  3686.     case  MASPAR_DISCONNECT:
  3687.       /*  disconnect maspar  */
  3688.       masParStatus = MASPAR_DISCONNECT;
  3689.  
  3690.       break;
  3691.     default:
  3692.       KernelErrorCode = KRERR_PARAMETERS;
  3693.   }
  3694.  
  3695.   return( KernelErrorCode );
  3696. }
  3697.  
  3698. /*****************************************************************************
  3699.   FUNCTION : kr_getMasParStatus
  3700.  
  3701.   PURPOSE  : 
  3702.   NOTES    : 
  3703.  
  3704.   RETURNS  : Returns the Status of the MasPar or an error code
  3705.   UPDATE   : 
  3706. ******************************************************************************/
  3707. krui_err  kr_getMasParStatus(void)
  3708. {
  3709.   KernelErrorCode = KRERR_NO_ERROR;
  3710.  
  3711.   return( masParStatus );
  3712. }
  3713.  
  3714. #endif
  3715.  
  3716.